@objc协议导致Swift编译器崩溃

3

我写了一个协议,其中有一些@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协议吗? - Jasper Blues
嘿,你在Session里声明了NSObject的子类吗? - Nate Cook
2个回答

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,所以感谢您提供的代码;) - André Fratelli
请问您能否看一下我的另一个问题?它与此相关:http://stackoverflow.com/questions/24591921/sessiondelegate-does-not-have-a-member-named-xxx - André Fratelli

1
抱歉,撤销我之前的编辑,请尝试按照以下方式操作:
@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.
    }
}

我的代码会导致编译器崩溃,所以它无法运行在iOS上...我会尝试你的答案,因为它是用Swift编写的,尽管@Nate Cook的解决方案已经起作用了=) - André Fratelli
去想想,它确实有效!但为什么?与只使用@objc相比,有@objc(PSessionDelegate)有什么区别? - André Fratelli
@André Fratelli,这并没有什么区别,因为您没有将其暴露给Objective C代码,我怀疑您的代码在其他地方崩溃了。 - vladof81
是的,没错。我不确定我是否已经清楚地表明了这个在编译时崩溃。编译器崩溃了,应用程序从未运行。因此,这几乎不可能是由于代码引起的。如果我不使用objc或使用Nate Cook的方法,一切都正常。 - André Fratelli
2
Objective-C版本只是一个解决方案,直到Swift和Xcode 6中的错误被解决——@AndréFratelli发布的第二个代码块很好(除了崩溃的Xcode问题)。 - Nate Cook
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接