最近在回答StackOverflow的問題時,發現performSelector方法在Swift被去掉,Apple的注釋是這個方法被去掉是因為不安全:
NOTE The performSelector: method and related selector-invoking methods are not imported in Swift because they are inherently unsafe.
如果在Swift調用這個方法會編譯出錯:
'performSelector' is unavailable: 'performSelector' methods are unavailable
反復嘗試後,我發現可以使用UIControl:
func sendAction(_ action: Selector, to target: AnyObject!, forEvent event: UIEvent!)
下面是一段演示代碼:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. var control:UIControl = UIControl() control.sendAction(Selector("greetings"), to: self, forEvent: nil) } func greetings() { println("greetings world") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
Log打印出:
greetings world
如果是Swift調用Objective-C類的target和action,可以參考下面的例子,假設有TestClass是Objective-C類,並且有getBarButtonItem返回UIBarButtonItem:
#import "TestClass.h" @implementation TestClass - (UIBarButtonItem *)getBarButtonItem { UIBarButtonItem *bar = [[UIBarButtonItem alloc] init]; bar.target = self; bar.action = @selector(help); return bar; } - (void)help { NSLog(@"Help offered"); } @end
那麼在Swift裡可以用下面的代碼執行help方法:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. var testClass = TestClass() var button: UIButton = UIButton() var barButtonItem = testClass.getBarButtonItem() button.sendAction(barButtonItem.action, to: barButtonItem.target, forEvent: nil) } }
Log打印出:
2014-07-06 23:49:49.942 TestApp [53986:2552835] Help offered
可以使用NSThread.detachNewThreadSelector,好處是可以使用延遲,並且可以附帶object,下面是掩飾代碼:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let delay = 2.0 * Double(NSEC_PER_SEC) var time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)) dispatch_after(time, dispatch_get_main_queue(), { NSThread.detachNewThreadSelector(Selector("greetings:"), toTarget:self, withObject: "sunshine") }) } func greetings(object: AnyObject?) { println("greetings world") println("attached object: \(object)") } }
使用NSTimer:
class func scheduledTimerWithTimeInterval(_ seconds: NSTimeInterval, target target: AnyObject!, selector aSelector: Selector, userInfo userInfo: AnyObject!, repeats repeats: Bool) -> NSTimer!