Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Apple's new programming language Swift handle blocks and asynchronous requests?

Tags:

C.f. Apple's website page on Swift: https://developer.apple.com/swift/

Are there blocks in Swift like in objective-c? How are they created and called?

How would do an asynchronous request in Swift?

Is it easy to create block related memory leaks in swift? If yes, how would you avoid them?

like image 262
Alexis Pribula Avatar asked Jun 03 '14 02:06

Alexis Pribula


People also ask

What is asynchronous programming in Swift?

An asynchronous function in Swift can give up the thread that it's running on, which lets another asynchronous function run on that thread while the first function is blocked. When an asynchronous function resumes, Swift doesn't make any guarantee about which thread that function will run on.

Is Swift general-purpose programming language?

Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. and the open-source community.


1 Answers

The Swift equivalent of an (Objective-)C block is called a closure. There's a whole chapter about them in The Swift Programming Language book.

Depending on the context where you use a closure, you can declare/use it with very concise syntax. For example, a method that takes a completion handler whose signature is (success: Bool, error: NSError) - > Void can be called like this:

someMethod(otherParameters: otherValues, completionHandler:{ success, error in     if !success { NSLog("I am a leaf on the wind: %@", error) } }) 

There's also a trailing closure syntax that reads nicely in cases where a closure essentially provides flow control. And you can drop the parameter names when you want to be really brief (at some cost to readability, but that's okay in some obvious cases like the below). Often a return statement is implicit, too.

myArray.sort { $0 < $1 } let squares = myArray.map { value in     value * 2 }     

Swift itself doesn't have anything for asynchronous requests, so you use existing API for that. You can use the trailing closure syntax, though:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {     // do some async stuff     NSOperationQueue.mainQueue().addOperationWithBlock {         // do some main thread stuff stuff     } } 

In most cases, you don't need to worry about creating reference cycles with Swift closures the way you do with ObjC blocks. To put it simply, the capture semantics are similar enough to "just work" the way you want it to for most stuff, but different enough that the common patterns for block/closure uses (e.g. dispatch to background/main thread and referencing self's properties) don't cause cycles.

Cycles are still possible, though, and there is a solution for them. This answer's a bit long already, so check out Strong Reference Cycles for Closures in the docs for the complete explanation.

like image 76
rickster Avatar answered Oct 11 '22 06:10

rickster