使用 #selector() 或 Selector() 的动态调度看不到您的 Swift 协议扩展。相反,如果可能的话,尝试完全避免 Objective-C。您可以使用 libdispatch 获得相同的结果:
protocol LazyUpdatable {
func waitToDoStuff()
func myMethodName()
}
extension LazyUpdatable {
func waitToDoStuff() {
let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1.5 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue()) {
self.myMethodName()
}
}
func myMethodName() {
print("Aloha!")
}
}
class ViewController: UIViewController, LazyUpdatable {
override func viewDidLoad() {
super.viewDidLoad()
waitToDoStuff()
}
}
当然,这不像使用选择器那么灵活,但可以让您使用真正的 Swift 协议扩展。
EDIT:如果您希望能够取消调用方法调用,请尝试以下操作:
var lazyUpdatableCancelKey = UInt8(0)
protocol LazyUpdatable: class {
func waitToDoStuff()
func cancelDoingStuff()
func myMethodName()
}
extension LazyUpdatable {
func waitToDoStuff() {
let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1.5 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue()) {
if let shouldCancel = objc_getAssociatedObject(self, &lazyUpdatableCancelKey) as? Bool where shouldCancel == true {
return
}
self.myMethodName()
}
}
func cancelDoingStuff() {
objc_setAssociatedObject(self, &lazyUpdatableCancelKey, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func myMethodName() {
print("Aloha!")
}
}
class ViewController: UIViewController, LazyUpdatable {
override func viewDidLoad() {
super.viewDidLoad()
waitToDoStuff()
let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1.4 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue()) {
self.cancelDoingStuff()
}
}
}