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 return
s 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 Thread
s 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
How to Use Nsuserdefaults to Store an Array of Custom Classes in Swift
iOS Swift Nsmutabledata Has No Member Appendstring
Start/Stop Image View Rotation Animations
How to Apply Multiple Masks to Uiview
iOS Swift 2 Record Video Avcapturesession
What's Happening Behind the Scenes in Xctest's @Testable
How to Share Published Model Between Two View Models in Swiftui
Xcode 6 Swift Wkwebview Keyboard Settings
Avplayer Not Full Screen in Landscape Mode Using iOS Swift
How Posting One Signal Notification's Additional Data and Receiving That
How to Add a Link for a Rate Button with Swift
How to Add Custom Data to Marker (Google Maps API Swift)
Differrence Between Closure and Function as Argument in Swift
-[Uithreadsafenode Canperformaction:Withsender:]: Unrecognized Selector Sent to Instance
Disable Vertical Scroll in Uiscrollview Swift
Xcode6/Swift: Unrecognized Selector Sent to Instance
How to Draw Text in Center to Uiimage
Uilocalnotification: Playing a Custom Audio File Saved in Documents Directory