objective-c - 从 Swift 扩展调用 Obj-C 属性时发生崩溃

标签 objective-c swift

使用此 Objective-C 属性:

@interface TSOnboardingPersonalizeViewController  
@property (nonatomic, weak) NSObject<PersonalizeContentCoordinatorDelegate> * _Nullable delegate;  
@end  

在 Swift 扩展中崩溃,如下所示:

extension TSOnboardingPersonalizeViewController {  
    func next() {  
        self.delegate?.performAction(.Forward)  
    }  
} 

POing self.delegate 显示:

(lldb) po self.delegate  
▿ Optional<protocol<PersonalizeContentCoordinatorDelegate>>  
  ▿ Some : <MyApp.PersonalizeContentCoordinator: 0x8e964cf58140>

但是如果我将属性转换为协议(protocol)类型,它不会崩溃:

extension TSOnboardingPersonalizeViewController {  
    func next() {  
        if let delegate = self.delegate as? PersonalizeContentCoordinatorDelegate {  
            delegate.performAction(.Forward)  
        }  
    }      
}  

POing 代表显示:

(lldb) po delegate  
<MyApp.PersonalizeContentCoordinator: 0x7f86bcf59930> 

为什么我需要将属性显式转换为 PersonalizeContentCoordinatorDelegate 协议(protocol)类型?

我使用的是 Swift 2.2 和 Xcode 7.3

最佳答案

我认为这可能是因为委托(delegate)是一个 NSObject,它可能没有 performAction 方法。因此,即使委托(delegate)符合 Objective-C 中的协议(protocol),Swift 也可能会看到一个 NSObject(它不包含该方法)。

这看起来像是“迷失在翻译中”之类的事情,Objective-C 告诉 Swift“这个对象符合这个协议(protocol)”。然后,在执行时,Swift 会尝试在 NSObject 上调用该方法,而 NSObject 显然不包含该方法并崩溃。这可以解释为什么强制转换会起作用,因为除非你告诉 Swift 你有一个特定类型的对象,否则它无法执行该类型的任何特定方法(即使底层对象实际上是该类型)。

不过,这只是一个猜测,绝对应该持保留态度(如果有的话,也许是一个更好的答案)。

关于objective-c - 从 Swift 扩展调用 Obj-C 属性时发生崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36631003/

相关文章:

iphone - 如何在iPhone中从ASIHTTPRequest调用soap方法?

ios - 将 UITextField 转换为逗号分隔的数字并返回点分隔符

下标中带有范围的 Swift 数组切片

ios - 当我向下移动它的 Y 原点时,UIView 容器消失了

arrays - 将类型 'Result?' 的值转换为类型 'String'

ios - 我可以使用 AVCaptureSession 从文件中读取视频吗?

ios - 如何在整个屏幕上创建透明覆盖,包括事件键盘

ios - 在标签上显示字符串和变量

ios - 基于指南针旋转 GMSMapView

ios - 如何使 Asynctask 中的 UIView 无效(swift,ios)