从Swift扩展调用Obj-C属性时崩溃

时间:2016-04-14 18:21:10

标签: 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>

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

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

POing代表显示:

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

为什么我需要明确地将属性强制转换为PersonalizeContentCoordinatorDelegate协议类型?

我正在使用Swift 2.2和Xcode 7.3

1 个答案:

答案 0 :(得分:0)

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

这似乎是一种“迷失在翻译中”的东西,其中Objective-C告诉Swift“这个对象符合这个协议。”然后在执行时,Swift尝试在NSObject上调用该方法,这显然不包括该方法并且崩溃。这可以解释为什么转换会起作用,因为在告诉Swift你有一个特定类型的对象之前,它不能执行任何类型的特定方法(即使底层对象实际上是那种类型)。

这只是一个猜测,但绝对应该用一粒盐(如果有的话可能会有更好的答案)。