June 3, 2014

Swift, iOS, and Threading

Posted in iPhone development, mac development tagged , , , , at 10:25 pm by tetontech

When learning a new language I usually follow the same pattern. I figure out how to do parallel processing, reflection, and build a few apps. Here is the beginning of my exploration of threading in Swift. I’m using NSOperations in this post and will look at GCD in a followup post.

Here are the steps:

  1. create a new swift file and inherit from NSOperation,
  2. override NSOperation’s main method,
  3. now create an instance of your new operation class,
  4. set the thread priority, and
  5. add it to an NSOperationQueue instance.

So far not different than Objective-C.

For this example I’m going to create a Sift class that inherits from NSOperation called BackgroundSillyness. Then I’ll use BackgroundSillyness in a Swift application’s ViewController viewDidLoad method.

Creating an instance of NSOperation:

    let queue = NSOperationQueue()

 

BackgroundSillyness.swift source

//import the Foundation library
import Foundation
//inherit from NSOperation
class BackGroundSillyness:NSOperation{
//override NSOperation's void main(void) method
 override func main() -> (){
       println("hello from background")
 }

So that is the class file. Now for the source from the ViewController. I’ll only include the source from the viewDidLoad method in order to keep things simple. You will recognize some of what is happening here if you are familiar with Objective-C.

ViewController.swift source

override func viewDidLoad() {
    super.viewDidLoad()
    // Create a new instance of BackGroundSillyness
    let backgroundOperation = BackGroundSillyness()
    /* I decided I wanted to figure out how to replace blocks with closures, 
    * soI set the completion block of the operation. 
    * 'hello' will now print outafter 'hello from background'.
    */ 
    queue.addOperation(backgroundOperation)
   //this is the default value, but if you don't set it you will get an error.
    backgroundOperation.threadPriority = 0
    backgroundOperation.completionBlock = {() -> () in 
        println("hello") 
    }
}

So there it is. All of the other properties of NSOperations can be set in the same way as the completion block. You can also leave out the ‘()->()  in’ portion of the closure if you want. Swift will infer the input and return types for you if you do.

When you run this, you may find that the background operation’s message is mixed up in the one printed out in the UI thread. It appears that Swift doesn’t queue up messages to the console. It isn’t a defect just something to be aware of. You could add a long running loop in the background operation’s main method if you would like to stop this from happening.

Now I’m off to figure out how to get Grand Central Dispatch (GCD) to work in Swift.

Advertisements

2 Comments »

  1. rlecheta said,

    the background task works, but it can’t update the view…in the closure block, I called tabletView.reloadData()… But it don’t reload. It seems that the view was not drawn. If I touch de view immediately the tableview is refreshed and show the new rows.

    • tetontech said,

      The example in the posting doesn’t show how to update the user interface. Any changes to the user interface must be done in the main app thread. There are multiple ways of doing this. You could create a new class that inherits from NSOperation, instantiate one of these new classes, and add it to the NSOperation.mainQueue() but that seems like a lot of work for little return.

      My suggestion would be to use Swift’s closures and do something like this.
      NSOperationQueue.mainQueue().addOperationWithBlock(){
      //update the UI element or elements
      }

      If you would like to see how to use NSOperationQueue without inheriting from NSOperation take a look at this posting.
      Another option, and the one that I usually prefer, is to use Grand Central Dispatch.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: