@objc 协议使 swift 编译器崩溃

Posted

技术标签:

【中文标题】@objc 协议使 swift 编译器崩溃【英文标题】:@objc protocol crashes the swift compiler 【发布时间】:2014-07-03 23:46:44 【问题描述】:

我写了 I 协议,它打算有一些 @optional 方法,但是 swift 编译器崩溃了。这有效:

protocol SessionDelegate 

    // TODO these should all be optional
    func willOpenSession(session: Session);
    func didOpenSession(session: Session);
    func didFailOpenningSession(session: Session, error: NSError!);

    func willCloseSession(session: Session);
    func didCloseSession(session: Session);

这不是:

@objc protocol SessionDelegate 

    @optional func willOpenSession(session: Session);
    @optional func didOpenSession(session: Session);
    @optional func didFailOpenningSession(session: Session, error: NSError!);

    @optional func willCloseSession(session: Session);
    @optional func didCloseSession(session: Session);

老实说,拥有@objc 足以让编译器崩溃。有什么解决办法吗?

【问题讨论】:

你的协议是否必须扩展 NSObject 协议? 嘿,你有没有将Session 声明为NSObject 的子类? 【参考方案1】:

目前,解决此问题的唯一方法是在 Objective-C 头文件中声明协议并通过 Objective-C 桥接头导入声明。

协议声明:

// SessionDelegate.h

@class Session;

@protocol SessionDelegate <NSObject>

@optional

- (void)willOpenSession:(Session *)session;
- (void)didOpenSession:(Session *)session;
- (void)didFailOpenningSession:(Session *)session error:(NSError *)error;

- (void)willCloseSession:(Session *)session;
- (void)didCloseSession:(Session *)session;

@end

桥接头:

// MyProject-Bridging-Header.h

#import "SessionDelegate.h"

Swift 中的一致性类实现:

// Session.swift

class Session 
    // ...


class MySessionDelegate: NSObject, SessionDelegate 
    func willOpenSession(session: Session) 
        // ...
    

【讨论】:

工作就像一个魅力!我从来没有学过objective-c,所以谢谢你的代码;) 你能看看我的另一个问题吗?相关:***.com/questions/24591921/…【参考方案2】:

抱歉,请修改我之前的编辑,尝试以下操作:

@objc(PSessionDelegate)
protocol PSessionDelegate 

    @optional func willOpenSession(session: Session);
    @optional func didOpenSession(session: Session);
    @optional func didFailOpenningSession(session: Session, error: NSError!);
    @optional func willCloseSession(session: Session);
    @optional func didCloseSession(session: Session);



class ViewController: UIViewController, PSessionDelegate 

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

【讨论】:

没有。我只是想让协议方法成为可选的。纯粹的 swift,objective-c 中什么都没有。 @André Fratelli,代码在 ios 7.1 设备上测试,没有崩溃,有趣的是你的代码也没有崩溃。 我的代码使编译器崩溃,所以它无法进入 iOS...我会尝试你的答案,因为它很快,尽管@Nate Cook 的解决方案已经奏效 =) 去看看,它确实有效!但为什么?有 @objc(PSessionDelegate) 而不是只有 @objc 有什么区别? Objective-C 版本只是一种解决方法,直到 Swift 和 Xcode 6 中的错误被消除 - @AndréFratelli 发布的第二个代码块很好(除了崩溃的 Xcode 事情)。

以上是关于@objc 协议使 swift 编译器崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Objc 代码找不到 swift 中定义的 Bool 变量

Swift 崩溃 libobjc.A.dylib objc_msgSend

Swift 中的 ObjC 协议实现

Swift 协议实现另一个@objc 协议

ObjC宏定义-预编译小功能

在我的 react-native 应用程序中的 Swift 中编译器生成的崩溃