protocol LazyUpdateable {
func waitToDoStuff()
func myMethodName()
}
extension LazyUpdateable where Self: NSObject {
func waitToDoStuff() {
self.performSelector(#selector(myMethodName), withObject: nil, afterDelay: 1.5)
}
func myMethodName() {
}
}
通过此更新,我得到了错误Argument of #selector refers to a method that is not exposed to objective c
,但是如果我使用旧版本,则会Selector("myMethodName")
收到警告,要求更改为更好的方法。#selector()
在这种情况下可以使用吗?@objc
我已经尝试过了,但无法在我的协议上进行设置。
这是您可以尝试显示的游乐场,不适用于设置 @objc
import Foundation
import UIKit
import XCPlayground
@objc protocol LazyUpdatable {
optional func waitToDoStuff()
optional func myMethodName()
}
extension LazyUpdatable where Self: UIViewController {
func waitToDoStuff() {
self.performSelector(#selector(myMethodName), withObject: nil, afterDelay: 1.5)
}
func myMethodName() {
print("LOL")
}
}
@objc
class AViewController: UIViewController, LazyUpdatable {
func start() {
waitToDoStuff()
}
}
let aViewController = AViewController()
aViewController.start()
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
使用#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协议扩展。
编辑:如果您希望能够取消调用方法调用,请尝试以下操作:
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()
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句