使用此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
答案 0 :(得分:0)
我认为这可能是因为委托是一个NSObject,它可能没有performAction
方法。因此,即使委托符合Objective-C中的协议,Swift也可能会看到一个NSObject(它不包含该方法)。
这似乎是一种“迷失在翻译中”的东西,其中Objective-C告诉Swift“这个对象符合这个协议。”然后在执行时,Swift尝试在NSObject上调用该方法,这显然不包括该方法并且崩溃。这可以解释为什么转换会起作用,因为在告诉Swift你有一个特定类型的对象之前,它不能执行任何类型的特定方法(即使底层对象实际上是那种类型)。
这只是一个猜测,但绝对应该用一粒盐(如果有的话可能会有更好的答案)。