Creating threads with parameters in Swift?
Asked Answered
W

3

6

I am trying to create a thread in swift and send two parameters. I create thread and this work:

let thread = NSThread(target:self, selector:"getData", object:nil)
thread.start()

But how to send parameters to my func getData? How to create object with parameters like this:

let params =...
let thread = NSThread(target:self, selector:"getData", object:params)
thread.start()

...

getData(username: String, password: String) {
    ...
}
Wirehaired answered 2/10, 2014 at 12:50 Comment(3)
Use of NSThread in Cocoa is almost always wrong. (On iOS, it's "always wrong" rather than "almost always wrong.") Apple has a very good document explaining how to convert thread-based constructions to Cocoa's concurrency model (called GCD). developer.apple.com/library/ios/documentation/General/…Overhead
@RobNapier NSThread as runloop that allows me to run it for ever. Do we have similar option in Swift using GCD?Velez
@Velez I assume you mean "it is possible to run an NSRunLoop forever within an NSThread." You can do the same thing in Swift; the overlays are called RunLoop and Thread. GCD is intentionally designed not to work that way. See the linked document above for the intended replacement designs. GCD is not just "threads with a new syntax." It employs a different design pattern. If you want to use the RunLoop+Thread design pattern, that still fully exists in Swift, it's just generally discouraged (and has been since OS X 10.6).Overhead
C
13

Instead of using threads directly, you should be using Grand Central Dispatch. In this case you'd want to use dispatch_async to call getData on a background queue:

let username = ...
let password = ...

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue) {
    getData(username, password);
}

Keep in mind that if getData actually returns data then you'll have to handle that inside dispatch_async's closure:

let username = ...
let password = ...

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue) {
    let someData = getData(username, password)
    /* do something with someData */
}

/* !! someData is NOT available here !! */

I highly recommend taking a look at Apple's Concurrency Programming Guide if you're going to be doing multithreaded / concurrent programming on iOS.

Convenance answered 2/10, 2014 at 14:24 Comment(7)
what if I want the thread to do an ongoing task as long as the app is running (it's an app for Mac actually) is using dispatch still safe? or in my case I should make my own thread since the app could be running as long as the computer is turned onMeghanmeghann
@OmarBizreh Sure. I'd suggest creating your own queue and running your task on there. I can only think of a few special cases where you might want an ongoing task like that though... you might want to take a look at dispatch_sources; I've found them to be a good fit when I'm tempted to create an ongoing task. There's a good intro to them here.Convenance
Thanks a lot Mike, I'll take a look at dispatch_source. As for what I'm doing I am using a lib for Socket connections so I want the app to listen to incoming requests all the time, is there a better approach than having a loop and waiting for a connection?Meghanmeghann
@OmarBizreh it really depends on how the socket lib is written, but dispatch_sources would typically be a good fit for that sort of thing.Convenance
Thanks Mike, its actually somewhat like .Net where I have a Listen() function that will just wait for someone to connect. so I'm going to loop on that function and handle received requests alone. I'll be going with dispatch_sources. However I found this github.com/anpol/DispatchKit do you recommend a newbie in swift to start with libs or should I do them my self for the sake of learning?Meghanmeghann
@OmarBizreh I haven't used DispatchKit myself so it's hard to say. I personally prefer to at least get familiar with things before deciding to use a library, but it's really just a matter of the way you learn I think.Convenance
Good point you have there. Thanks for your help I'll take it from here. I really appreciate it.Meghanmeghann
B
3

What about creating a class to hold your parameters?

class Params {
    username: String
    password: String
    init (#username: String, password: String) {
        self.username = username
        self.password = password
    }
}
// ...
let thread = NSThread(target:self, selector:"getData:", object:Params(username:"xyz", password:"abc")
thread.start()
// ...
func getData(params: Params) {
    // ...
}
Brogan answered 2/10, 2014 at 13:21 Comment(1)
This is the only option when using threads. I'd consider using dispatch_async for this though.Kreiker
C
3

Updated with Swift 5

Thread.detachNewThreadSelector(#selector(getData), toTarget: self, with: params)
func getData(params: Params) {
    // ...
}
Cletuscleve answered 19/2, 2020 at 10:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.