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

Very funny error on Xcode 8.0 beta 3 in accessing function from notifications and timers

我从 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()

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

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

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

假设你周围的代码没有错误(你应该检查,因为 Xcode 8 beta 经常给出不能描述实际问题的错误),你需要确保你正在创建的函数选择器for 对 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 以避免选择器。

原因仅仅是因为我忘记添加参数'notification:'。

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

工作正常。