Creating Threads in Swift

Creating threads with parameters in Swift?

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.

How to create and run a Thread in Swift using the Foundation framework?

Thread (NSThread in Objective-C) is a fairly thin wrapper around POSIX threads. It has some extra plumbing to interact with Apple's Foundation framework (which is common between iOS and Mac OS.)

The idea of targets and selectors is part of the Objective-C runtime, which is the basis of AppKit on Mac OS and UIKit for iOS. A selector is a method signature for the Objective-C dynamic method dispatch system. A target is an object that will receive a method call using a given selector.

Note that the Thread class also has an initializer that takes a closure rather than a target/action. If you're determined to use Threads you could use that initializer instead (It will call your closure when it's started.)
That initializer is convenience init(block: @escaping () -> Void)

As others have said, you are better off using Grand Central Dispatch (GCD) for a couple of reasons.

  • It is not tied to the Objective-C runtime.

  • Creating and destroying threads is pretty expensive, needs a kernel
    call, and ties up physical memory for the lifetime of the thread.

CGD lets the system maintain a pool of threads on your behalf. You either use an existing dispatch queue or create one of your own, and the system decides which threads to assign to that queue from a pool of threads.

It is also much cleaner to use from Swift than the Thread (NSThread) class.

Note that you could also ignore the Thread class and create POSIX threads directly, although I wouldn't really recommend that.

Creating threads in swift?

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)

Create threads from a dispatch queue block [ swift / c++ ]

will those threads that I create within the c++ library be separate from the work queue in swift ?

The answer is yes. I'm doing the same things for my app. For C++ library, I believe you will create threads with pthread_create() POSIX call. As found in Apple's doc, POSIX threads are totally legal in iOS and the only way to create joinable threads.

how to start a global thread in swift

Use Grand Central Dispatch

    let myQueue: dispatch_queue_t = dispatch_queue_create("com.example.queue", nil)
dispatch_async(myQueue, { () -> Void in
// Execute some code
})

Is asynchronous code always run on a different thread?

@escaping does NOT determine which thread the closure is ran on. The documentation does.

For that specific function (https://developer.apple.com/documentation/contacts/cncontactstore/1402873-requestaccess/):

The system executes completionHandler on an arbitrary queue. It is recommended that you use CNContactStore instance methods in this completion handler instead of the UI main thread.

If you are doing any sort of UI work inside of the completionHandler callback, it means you MUST call DispatchQueue.main.async { update_my_UI_here() } to execute your code safely on the main thread.

Example:

requestAccess(for: .contacts) { [weak self] permissionGranted, error in
//All code in here is ran on an ARBITRARY background queue

if let error = error {
log(error)
return
}

//CNContactStore - Any CNContactStore functions should run here, and not inside `DispatchQueue.main`

guard let self = self else { return }

// Any UI updates or any code that interacts with `UI*` or constraints, must be done on main
DispatchQueue.main.async {
self.update_my_ui_here(permisionGranted) //Safely update UI from the main queue
}
}

Marking a function as @escaping just means that it may POTENTIALLY be called at a later time or stored as a variable somewhere. That's all it means. It does NOT mean that is will be ran on the same OR a different thread. It doesn't have any guarantees about threads and it doesn't have any guarantees about when it will run.

After all, DispatchQueue.main.async(completion: @escaping () -> Void) has an escaping parameter, and yet it always runs the completion on the exact same main thread. main is the only queue with such guarantee, regardless of whether the parameter is escaping or not.



Related Topics



Leave a reply



Submit