Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to performSelector in Swift?

The performSelector family of methods are not available in Swift. So how can you call a method on an @objc object, where the method to be called is chosen at runtime, and not known at compile time? NSInvocation is apparently also not available in Swift.

I know that in Swift, you can send any method (for which there is an @objc method declaration visible) to the type AnyObject, similar to id in Objective-C. However, that still requires you to hard-code the method name at compile-time. Is there a way to dynamically choose it at runtime?

like image 703
user102008 Avatar asked Jun 11 '14 08:06

user102008


2 Answers

Using closures

class A {     var selectorClosure: (() -> Void)?      func invoke() {         self.selectorClosure?()     } }  var a = A() a.selectorClosure = { println("Selector called") } a.invoke() 

Note that this is nothing new, even in Obj-C the new APIs prefer using blocks over performSelector (compare UIAlertView which uses respondsToSelector: and performSelector: to call delegate methods, with the new UIAlertController).

Using performSelector: is always unsafe and doesn't play well with ARC (hence the ARC warnings for performSelector:).

like image 72
Sulthan Avatar answered Oct 15 '22 14:10

Sulthan


As of Xcode 7, the full family of performSelector methods are available in Swift, including performSelectorOnMainThread() and performSelectorInBackground(). Enjoy!

like image 39
FizzBuzz Avatar answered Oct 15 '22 15:10

FizzBuzz