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 应用程序