【问题标题】:Crash when calling Obj-C property from Swift extension从 Swift 扩展调用 Obj-C 属性时崩溃
【发布时间】:2016-04-14 18:21:10
【问题描述】:

使用这个 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

【问题讨论】:

    标签: objective-c swift


    【解决方案1】:

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

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

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

    【讨论】:

    • Swift 不将其视为 NSObject,而是将其视为 >。使用 id 也无济于事。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 2022-08-20
    • 2016-05-01
    • 2014-12-05
    • 1970-01-01
    相关资源
    最近更新 更多