Xcode 8.0 beta 3 在从通知和计时器访问功能时出现非常有趣的错误

Posted

技术标签:

【中文标题】Xcode 8.0 beta 3 在从通知和计时器访问功能时出现非常有趣的错误【英文标题】:Very funny error on Xcode 8.0 beta 3 in accessing function from notifications and timers 【发布时间】:2016-07-25 09:26:15 【问题描述】:

我从 Xcode 收到了这个非常奇怪且相当可笑的错误: 执行时:

NotificationCenter.default.addObserver(self, selector:#selector(Booking.loadElement(_:)), name:String(format:"portal%d", portalIdent), object:nil)

还有:

Timer(timeInterval:5, target:self, selector:#selector(Booking.bookingTimerMethod(_:)), userInfo:"load", repeats:false).fire()

如您所见,编译器抱怨函数不存在并建议我使用相同的函数!

这是什么,我该如何弥补?

【问题讨论】:

我在这里看不到您的所有代码,但是您是否将 bookingTimerMethod 设置为类 func 或常规 func。将其引用为 Booking.bookingTimerMethod 需要将该方法声明为类 func。 @jacobbullock 根据我的经验,#selector 语句对于是否包含类型名称并没有那么严格,即使是实例方法也是如此。 @MatthewSeaman 我认为这是真的,如果它在同一个类中,他不需要包含 Booking 参考。但是通过这种方式添加它,我认为它会寻找一个静态(类)函数而不是标准函数,这会引发错误。虽然我还没有测试过。 【参考方案1】:

到目前为止,Xcode 8 有一些非常古怪的错误消息,这些错误消息通常不会导致问题,所以现在让我们忽略这些消息。

假设你周围的代码没有错误(你应该检查,因为 Xcode 8 beta 经常给出不能描述实际问题的错误),你需要确保你正在为其创建选择器的函数对 Objective-可见C 而不仅仅是 Swift,因为您使用的 API 是用 Objective-C 编写的。

#selector 不仅强制方法存在,而且它们对 Objective-C 可见。

要对 Objective-C 可见,以下至少一项(不是全部)必须为真:

类型子类NSObject 直接或间接 方法本身是用@objc 属性编写的,特别是如果它是私有方法。

如果这些都是真的,那么这些方法显然存在,并且您已经彻底检查了周围的代码,file a bug report。

选择器的替代方案

您可以完全避免在 beta SDK 中使用 Timer 的选择器,而是使用采用闭包的新 swift-friendly Timer init,然后从那里调用您的函数。但是,他可能会要求您围绕没有userInfo 进行设计。

同样,在NotificationCenter 上查看this Swift-friendly addObserver function,避免选择器。

【讨论】:

【参考方案2】:

原因很简单,因为我忘记添加参数“通知:”。

NotificationCenter.default.addObserver(self, selector:#selector(Booking.loadElement(notification:)), name:NSNotification.Name(rawValue: String(format:"portal%d", portalIdent!)), object:nil)

工作得很好。

【讨论】:

以上是关于Xcode 8.0 beta 3 在从通知和计时器访问功能时出现非常有趣的错误的主要内容,如果未能解决你的问题,请参考以下文章

推送通知不适用于 testflight 和 xcode 8 beta

Xcode6-Beta3 更新后,无法使用 Swift 访问键盘信息

Fabric Answer 在从 Xcode 10 和 iOS 12 开始时崩溃 iOS 应用程序

在 Xcode 8 和 Swift 3.0 中删除覆盖后准备 segue 崩溃

未安装自定义字体 - Xcode 11 beta

提交二进制文件进行 Beta 测试:“缺少推送通知权利”