9

I am trying to spawn a thread in swift. So I have this line:

. . .

let thread = NSThread(target: self, selector: doSomething(), object: nil)

. . .

doSomething is a function within the scope of the class.

That line gives this error: "could not find an overload for init() that accepts the supplied arguments"

What am I missing here? Ho can I create a new thread in swift?

zumzum
  • 17,984
  • 26
  • 111
  • 172

3 Answers3

13

As of Xcode 7.3 and Swift 2.2, you can use the special form #selector(...) where Objective-C would use @selector(...):

let thread = NSThread(target:self, selector:#selector(doSomething), object:nil)
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • How would you do it if `doSomething` required an argument (say of type `NSString`)? – Matt Jul 04 '14 at 21:32
  • That is what the `object` argument is for. – rob mayoff Jul 04 '14 at 21:40
  • I tried that, but I keep getting an `NSInvalidArgumentException`: `[NSThread initWithTarget:selector:object:]: target does not implement selector`. It apparently doesn't recognize my function name. (Should I post this as a new question?) – Matt Jul 04 '14 at 21:44
  • 4
    If the selector takes an argument then it must end with a colon. Example: `NSThread(target:self, selector:"doSomethingWithObject:", object:someObject)` – rob mayoff Jul 05 '14 at 03:57
  • @Matt Make sure that your target class inherits from `NSObject`. – kaolick May 18 '15 at 17:01
  • @kaolick doesn't every class automatically inherit from `NSObject`? – Matt May 18 '15 at 19:00
  • @Matt Possibly not. I had the same problem that you mentioned above. I could only solve it by letting my class inherit from NSObject. To my excuse I should mention that this was my first try with Swift though... – kaolick May 18 '15 at 19:03
  • 2
    No, classes don't inherit from `NSObject` by default. If you make a subclass of anything in the Cocoa Touch frameworks, it will inherit `NSObject` indirectly. Otherwise, in Swift, you need to explicitly inherit from `NSObject`, or declare your class `@objc`, in order to use it with `NSThread`. – rob mayoff May 18 '15 at 19:06
  • In Swift 2.2, you now use #selector(doSomething). – crimson_penguin Apr 07 '16 at 23:44
4

NSThread takes a selector as it's second parameter. You can describe Objective-C selectors as Strings in Swift like this:

let thread = NSThread(target: myObj, selector: "mySelector", object: nil)

Swift functions aren't equivalent objective-c methods though. If you have a method in a swift class, you can use it as a selector if you use the @objc attribute on the class:

@objc class myClass{
    func myFunc(){
    }
}

var myObj = myClass()
let thread = NSThread(target: myObj, selector: "myFunc", object: nil)
Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
0
  1. When we call a selector on a target, we should check if the target exists and it responds to the selector. Only class that extend from NSObject or it's subclasses can use respondsToSelector:

  2. You can use a NSDictionary to store parameters if you have more than 2 parameters.

    Ex:

    //this code is in Objective-C but the same code should exist in Swift
    
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:object1, @"key1", object2, @"key2",nil]; 
    

then pass 'params' to parameter of selector:

SkrewEverything
  • 2,393
  • 1
  • 19
  • 50
Duyen-Hoa
  • 15,384
  • 5
  • 35
  • 44