a view controller manages a screenful of content. This has since changed to
a view controller manages a self-contained unit of content. Why didn't Apple want us to build our own tab bar controllers and navigation controllers? Or put more precisely, what is the problem with: ```objc [viewControllerA.view addSubView:viewControllerB.view] ```  The UIWindow, which serves as an app's root view, is where rotation and initial layout messages originate from. In the illustration above, the child view controller, whose view was inserted in the root view controller view hierarchy, is excluded from those events. View event methods like `viewWillAppear:` will not get called. The custom view controller containers built before iOS 5 would keep a reference to the child view controllers and manually relay all the view event methods called on the parent view controller, which is pretty difficult to get right. ## An Example When you were a kid playing in the sand, did your parents ever tell you that if you kept digging with your little shovel you would end up in China? Mine did, and I made a small demo app called *Tunnel* to test this claim. You can clone the [GitHub repo](https://github.com/objcio/issue-1-view-controller-containment) and run the app, which will make it easier to understand the example code. *(Spoiler: digging through the earth from western Denmark lands you somewhere in the South Pacific Ocean.)*  To find the antipode, as the opposite location is called, move the little guy with the shovel around and the map will tell you where your exit location is. Tap the radar button and the map will flip to reveal the name of the location. There are two map view controllers on screen. Each of them has to deal with dragging, annotation, and updating the map. Flipping these over reveals two new view controllers which reverse geocode the locations. All the view controllers are contained inside a parent view controller, which holds their views, and ensures that layout and rotation behaves as expected. The root view controller has two container views. These are added to make it easier to layout and animate the views of child view controllers, as we will see later on. ```objc - (void)viewDidLoad { [super viewDidLoad]; //Setup controllers _startMapViewController = [RGMapViewController new]; [_startMapViewController setAnnotationImagePath:@"man"]; [self addChildViewController:_startMapViewController]; // 1 [topContainer addSubview:_startMapViewController.view]; // 2 [_startMapViewController didMoveToParentViewController:self]; // 3 [_startMapViewController addObserver:self forKeyPath:@"currentLocation" options:NSKeyValueObservingOptionNew context:NULL]; _startGeoViewController = [RGGeoInfoViewController new]; // 4 } ``` The `_startMapViewController`, which displays the starting position, is instantiated and set up with the annotation image. 1. The `_startMapViewController` is added as a child of the root view controller. This automatically calls the method `willMoveToParentViewController:` on the child. 2. The child's view is added as a subview of the first container view. 3. The child is notified that it now has a parent view controller. 4. The child view controller that does the geocoding is instantiated, but not inserted in any view or controller hierarchy yet. ## Layout The root view controller defines the two container views, which determine the size of the child view controllers. The child view controllers do not know which container they will be added to, and therefore have to be flexible in size: ```objc - (void) loadView { mapView = [MKMapView new]; mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight; [mapView setDelegate:self]; [mapView setMapType:MKMapTypeHybrid]; self.view = mapView; } ``` Now they will layout using the bounds of their super view. This increases the reusability of the child view controller; if we were to push it on the stack of a navigation controller, it would still layout correctly. ## Transitions Apple has made the view controller containment API so fine-grained that it is possible to construct and animate any containment scenario we can think of. Apple also provides a block-based convenience method for exchanging two controller views on the screen. The method `transitionFromViewController:toViewController:(...)` takes care of a lot of the details for us: ```objc - (void) flipFromViewController:(UIViewController*) fromController toViewController:(UIViewController*) toController withDirection:(UIViewAnimationOptions) direction { toController.view.frame = fromController.view.bounds; // 1 [self addChildViewController:toController]; // [fromController willMoveToParentViewController:nil]; // [self transitionFromViewController:fromController toViewController:toController duration:0.2 options:direction | UIViewAnimationOptionCurveEaseIn animations:nil completion:^(BOOL finished) { [toController didMoveToParentViewController:self]; // 2 [fromController removeFromParentViewController]; // 3 }]; } ``` 1. Before the animation we add the `toController` as a child and we inform the `fromController` that it will be removed. If the fromController's view is part of the container's view hierarchy, this is where `viewWillDisappear:` is called. 2. `toController` is informed of its new parent, and appropriate view event methods will be called. 3. The `fromController` is removed. This convenience method for view controller transitions automatically swaps out the old view controller's view for the new one. However, if you implement your own transition and you wish to only display one view at a time, you have to call `removeFromSuperview` on the old view and `addSubview:` for the new view yourself. Getting the sequence of method calls wrong will most likely result in an `UIViewControllerHierarchyInconsistency` warning. For example, this will happen if you call `didMoveToParentViewController:` before you added the view. In order to be able to use the `UIViewAnimationOptionTransitionFlipFromTop` animation, we had to add the children's views to our view containers instead of to the root view controller's view. Otherwise the animation would result in the entire root view flipping over. ## Communication View controllers should be reusable and self-contained entities. Child view controllers are no exception to this rule of thumb. In order to achieve this, the parent view controller should only be concerned with two tasks: laying out the child view controller's root view, and communicating with the child view controller through its exposed API. It should never modify the child's view tree or other internal state directly. Child view controllers should contain the necessary logic to manage their view trees themselves -- don't treat them as dumb views. This will result in a clearer separation of concerns and better reusability. In the Tunnel example app, the parent view controller observes a property called `currentLocation` on the map view controllers: ```objc [_startMapViewController addObserver:self forKeyPath:@"currentLocation" options:NSKeyValueObservingOptionNew context:NULL]; ``` When this property changes in response to moving the little guy with the shovel around on the map, the parent view controller communicates the antipode of the new location to the other map: ```objc [oppositeController updateAnnotationLocation:[newLocation antipode]]; ``` Likewise, when you tap the radar button, the parent view controller sets the locations to be reverse geocoded on the new child view controllers: ```objc [_startGeoViewController setLocation:_startMapViewController.currentLocation]; [_targetGeoViewController setLocation:_targetMapViewController.currentLocation]; ``` Independent of the technique you choose to communicate from child to parent view controllers (KVO, notifications, or the delegate pattern), the goal always stays the same: the child view controllers should be independent and reusable. In our example we could push one of the child view controllers on a navigation stack, but the communication would still work through the same API. ================================================ FILE: 2013-06-07-introduction.markdown ================================================ --- title: "Introduction" category: "1" date: "2013-06-07 12:00" tags: editorial --- Welcome to the first edition of objc.io, a periodical about best practices and advanced techniques in Objective-C! objc.io was founded in Berlin by [Chris Eidhof](https://twitter.com/chriseidhof), [Daniel Eggert](https://twitter.com/danielboedewadt), and [Florian Kugler](https://twitter.com/floriankugler). We started objc.io to create a regular platform for in-depth technical topics relevant to all iOS and OS X developers. Each edition of objc.io has a focus on one particular subject, with multiple articles covering different aspects of that topic. The subject of this first edition is *Lighter View Controllers*, and it contains four articles – three from the founding team and one from [Ricki Gregersen](https://twitter.com/rickigregersen), whom we would like to welcome as our first guest writer! It's a common problem in the code base of iOS apps that view controllers get out of hand, because they do too much. By factoring out reusable code, they are easier to understand, easier to maintain and easier to test. This issue will focus on best practices and techniques how you can keep view controllers clean. We will look at how to make view controllers primarily coordinating objects by factoring out view and model code, as well as introducing other controller objects in addition to view controllers. Furthermore, we will look at splitting up view controllers using the view controller containment mechanism, and finally, discuss how to test clean view controllers. In upcoming editions we will have more articles from great guest writers of the Objective-C community; [Loren Brichter](https://twitter.com/lorenb), [Peter Steinberger](https://twitter.com/steipete), [Brent Simmons](https://twitter.com/brentsimmons), and [Ole Begemann](https://twitter.com/olebegemann) have committed to writing in the future. [Contact us](mailto:mail@objc.io) if you have an idea for an interesting topic and you would like to contribute an article about it to objc.io. Chris, Daniel, and Florian. ================================================ FILE: 2013-06-07-lighter-view-controllers.md ================================================ --- title: "Lighter View Controllers" category: "1" date: "2013-06-07 11:00:00" author: - name: Chris Eidhof url: http://twitter.com/chriseidhof tags: article --- View controllers are often the biggest files in iOS projects, and they often contain way more code than necessary. Almost always, view controllers are the least reusable part of the code. We will look at techniques to slim down your view controllers, make code reusable, and move code to more appropriate places. The [example project](https://github.com/objcio/issue-1-lighter-view-controllers) for this issue is on GitHub. ## Separate Out Data Source and Other Protocols One of the most powerful techniques to slim down your view controller is to take the `UITableViewDataSource` part of your code, and move it to its own class. If you do this more than once, you will start to see patterns and create reusable classes for this. For example, in our example project, there is a class `PhotosViewController` which had the following methods: ```objc # pragma mark Pragma - (Photo*)photoAtIndexPath:(NSIndexPath*)indexPath { return photos[(NSUInteger)indexPath.row]; } - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { return photos.count; } - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { PhotoCell* cell = [tableView dequeueReusableCellWithIdentifier:PhotoCellIdentifier forIndexPath:indexPath]; Photo* photo = [self photoAtIndexPath:indexPath]; cell.label.text = photo.name; return cell; } ``` A lot of this code has to do with arrays, and some of it is specific to the photos that the view controller manages. So let's try to move the array-related code into its [own class](https://github.com/objcio/issue-1-lighter-view-controllers/blob/master/PhotoData/ArrayDataSource.h). We use a block for configuring the cell, but it might as well be a delegate, depending on your use-case and taste. ```objc @implementation ArrayDataSource - (id)itemAtIndexPath:(NSIndexPath*)indexPath { return items[(NSUInteger)indexPath.row]; } - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { return items.count; } - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { id cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; id item = [self itemAtIndexPath:indexPath]; configureCellBlock(cell,item); return cell; } @end ``` The three methods that were in your view controller can go, and instead you can create an instance of this object and set it as the table view's data source. ```objc void (^configureCell)(PhotoCell*, Photo*) = ^(PhotoCell* cell, Photo* photo) { cell.label.text = photo.name; }; photosArrayDataSource = [[ArrayDataSource alloc] initWithItems:photos cellIdentifier:PhotoCellIdentifier configureCellBlock:configureCell]; self.tableView.dataSource = photosArrayDataSource; ``` Now you don't have to worry about mapping an index path to a position in the array, and every time you want to display an array in a table view you can reuse this code. You can also implement additional methods such as `tableView:commitEditingStyle:forRowAtIndexPath:` and share that code among all your table view controllers. The nice thing is that we can [test this class](/issues/1-view-controllers/testing-view-controllers/#testing-a-data-source) separately, and never have to worry about writing it again. The same principle applies if you use something else other than arrays. In one of the applications we were working on this year, we made heavy use of Core Data. We created a similar class, but instead of being backed by an array, it is backed by a fetched results controller. It implements all the logic for animating the updates, doing section headers, and deletion. You can then create an instance of this object and feed it a fetch request and a block for configuring the cell, and the rest will be taken care of. Furthermore, this approach extends to other protocols as well. One obvious candidate is `UICollectionViewDataSource`. This gives you tremendous flexibility; if, at some point during the development, you decide to have a `UICollectionView` instead of a `UITableView`, you hardly have to change anything in your view controller. You could even make your data source support both protocols. ## Move Domain Logic into the Model Here is an example of code in view controller (from another project) that is supposed to find a list of active priorities for a user: ```objc - (void)loadPriorities { NSDate* now = [NSDate date]; NSString* formatString = @"startDate <= %@ AND endDate >= %@"; NSPredicate* predicate = [NSPredicate predicateWithFormat:formatString, now, now]; NSSet* priorities = [self.user.priorities filteredSetUsingPredicate:predicate]; self.priorities = [priorities allObjects]; } ``` However, it is much cleaner to move this code to a category on the `User` class. Then it looks like this in `View Controller.m`: ```objc - (void)loadPriorities { self.priorities = [self.user currentPriorities]; } ``` and in `User+Extensions.m`: ```objc - (NSArray*)currentPriorities { NSDate* now = [NSDate date]; NSString* formatString = @"startDate <= %@ AND endDate >= %@"; NSPredicate* predicate = [NSPredicate predicateWithFormat:formatString, now, now]; return [[self.priorities filteredSetUsingPredicate:predicate] allObjects]; } ``` Some code cannot be easily moved into a model object but is still clearly associated with model code, and for this, we can use a `Store`: ## Creating the Store Class In the first version of our example application, we had some code to load data from a file and parse it. This code was in the view controller: ```objc - (void)readArchive { NSBundle* bundle = [NSBundle bundleForClass:[self class]]; NSURL *archiveURL = [bundle URLForResource:@"photodata" withExtension:@"bin"]; NSAssert(archiveURL != nil, @"Unable to find archive in bundle."); NSData *data = [NSData dataWithContentsOfURL:archiveURL options:0 error:NULL]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; _users = [unarchiver decodeObjectOfClass:[NSArray class] forKey:@"users"]; _photos = [unarchiver decodeObjectOfClass:[NSArray class] forKey:@"photos"]; [unarchiver finishDecoding]; } ``` The view controller should not have to know about this. We created a *Store* object that does just this. By separating it out, we can reuse that code, test it separately and keep our view controller small. The store can take care of data loading, caching, and setting up the database stack. This store is also often called a *service layer* or a *repository*. ## Move Web Service Logic to the Model Layer This is very similar to the topic above: don't do web service logic in your view controller. Instead, encapsulate this in a different class. Your view controller can then call methods on this class with a callback handler (for example, a completion block). The nice thing is that you can do all your caching and error handling in this class too. ## Move View Code into the View Layer Building complicated view hierarchies shouldn't be done in view controllers. Either use interface builder, or encapsulate views into their own `UIView` subclasses. For example, if you build your own date picker control, it makes more sense to put this into a `DatePickerView` class than creating the whole thing in the view controller. Again, this increases reusability and simplicity. If you like Interface Builder, then you can also do this in Interface Builder. Some people assume you can only use this for view controllers, but you can also load separate nib files with your custom views. In our example app, we created a [`PhotoCell.xib`](https://github.com/objcio/issue-1-lighter-view-controllers/blob/master/PhotoData/PhotoCell.xib) that contains the layout for a photo cell:  As you can see, we created properties on the view (we don't use the File's Owner object in this xib) and connect them to specific subviews. This technique is also very handy for other custom views. ## Communication One of the other things that happen a lot in view controllers is communication with other view controllers, the model, and the views. While this is exactly what a controller should do, it is also something we'd like to achieve with as minimal code as possible. There are a lot of well-explained techniques for communication between your view controllers and your model objects (such as KVO and fetched results controllers), however, communication between view controllers is often a bit less clear. We often have the problem where one view controller has some state and communicates with multiple other view controllers. Often, it then makes sense to put this state into a separate object and pass it around the view controllers, which then all observe and modify that state. The advantage is that it's all in one place, and we don't end up entangled in nested delegate callbacks. This is a complex subject, and we might dedicate a whole issue to this in the future. ## Conclusion We've seen some techniques for creating smaller view controllers. We don't strive to apply these techniques wherever possible, as we have only one goal: to write maintainable code. By knowing these patterns, we have better chances of taking unwieldy view controllers and making them clearer. ### Further Reading * [View Controller Programming Guide for iOS](http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html) * [Cocoa Core Competencies: Controller Object](http://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/ControllerObject.html) * [Writing high quality view controllers](http://subjective-objective-c.blogspot.de/2011/08/writing-high-quality-view-controller.html) * [Programmers Stack Exchange: Model View Controller Store](http://programmers.stackexchange.com/questions/184396/mvcs-model-view-controller-store) * [Unburdened View Controllers](https://speakerdeck.com/trianglecocoa/unburdened-viewcontrollers-by-jay-thrash) * [Programmers Stack Exchange: How to avoid big and clumsy `UITableViewControllers` on iOS](http://programmers.stackexchange.com/questions/177668/how-to-avoid-big-and-clumsy-uitableviewcontroller-on-ios) ================================================ FILE: 2013-06-07-table-views.md ================================================ --- title: "Clean Table View Code" category: "1" date: "2013-06-07 10:00:00" author: - name: Florian Kugler url: http://twitter.com/floriankugler tags: article --- Table views are an extremely versatile building block for iOS apps. Therefore, a lot of code is directly or indirectly related to table view tasks, including supplying data, updating the table view, controlling its behavior, and reacting to selections, to name just a few. In this article, we will present techniques to keep this code clean and well-structured. ## UITableViewController vs. UIViewController Apple provides `UITableViewController` as dedicated view controller class for table views. Table view controllers implement a handful of very useful features which can help you to avoid writing the same boilerplate code over and over. On the flip side, table view controllers are restricted to managing exactly one table view, which is presented full screen. However, in many cases, this is all you need, and if it's not, there are ways to work around this, as we will show below. ### Features of Table View Controllers Table view controllers help you with loading the table view's data when it is shown for the first time. More specifically, it helps with toggling the table view's editing mode, with reacting to the keyboard notifications, and with a few small tasks like flashing the scroll indicator and clearing the selection. In order for these features to work, it is important that you call super on any view event methods (such as `viewWillAppear:` and `viewDidAppear:`) that you may override in your custom subclass. Table view controllers have one unique selling point over standard view controllers, and that's the support for Apple's implementation for "pull to refresh." At the moment, the only documented way of using `UIRefreshControl` is within a table view controller. There are ways to make it work in other contexts, but these could easily not work with the next iOS update. The sum of all these elements provides much of the standard table view interface behavior as Apple has defined it. If your app conforms to these standards, it is a good idea to stick with table view controllers in order to avoid writing boilerplate code. ### Limitations of Table View Controllers The view property of table view controllers always has to be set to a table view. If you decide later on that you want to show something else on the screen aside from the table view (e.g. a map), you are out of luck if you don't want to rely on awkward hacks. If you have defined your interface in code or using a .xib file, then it is pretty easy to transition to a standard view controller. If you're using storyboards, then this process involves a few more steps. With storyboards, you cannot change a table view controller to a standard view controller without recreating it. This means you have to copy all the contents over to the new view controller and wire everything up again. Finally, you need to add back the features of table view controller that you lost in this transition. Most of them are simple single-line statements in `viewWillAppear` or `viewDidAppear`. Toggling the editing state requires implementing an action method which flips the table view's `editing` property. The most work lies in recreating the keyboard support. Before you go down this route though, here is an easy alternative that has the additional benefit of separating concerns: ### Child View Controllers Instead of getting rid of the table view controller entirely, you could also add it as a child view controller to another view controller (see the [article about view controller containment](/issues/1-view-controllers/containment-view-controller/) in this issue). Then the table view controller continues to manage only the table view and the parent view controller can take care of whatever additional interface elements you might need. ```objc - (void)addPhotoDetailsTableView { DetailsViewController *details = [[DetailsViewController alloc] init]; details.photo = self.photo; details.delegate = self; [self addChildViewController:details]; CGRect frame = self.view.bounds; frame.origin.y = 110; details.view.frame = frame; [self.view addSubview:details.view]; [details didMoveToParentViewController:self]; } ``` If you use this solution you have to create a communication channel from the child to the parent view controller. For example, if the user selects a cell in the table view, the parent view controller needs to know about this in order to push another view controller. Depending on the use case, often the cleanest way to do this is to define a delegate protocol for the table view controller, which you then implement on the parent view controller. ```objc @protocol DetailsViewControllerDelegate - (void)didSelectPhotoAttributeWithKey:(NSString *)key; @end @interface PhotoViewController ()
If you always read or write a file’s contents from start to finish, streams provide a simple interface for doing so asynchronously.. Whether you use streams or not, the general pattern for reading a file line-by-line is as follows: 1. Have an intermediate buffer that you append to while not finding a newline 2. Read a chunk from the stream 3. For each newline found in the chunk, take the intermediate buffer, append data from the stream up to (and including) the newline, and output that 4. Append the remaining bytes to the intermediate buffer 5. Go back to 2 until the stream closes To put this into practice, we created a [sample application](https://github.com/objcio/issue-2-background-file-io) with a `Reader` class that does just this. The interface is very simple: ```objc @interface Reader : NSObject - (void)enumerateLines:(void (^)(NSString*))block completion:(void (^)())completion; - (id)initWithFileAtPath:(NSString*)path; @end ``` Note that this is not a subclass of `NSOperation`. Like URL connections, input streams deliver their events using a run loop. Therefore, we will use the main run loop again for event delivery, and then dispatch the processing of the data onto a background operation queue. ```objc - (void)enumerateLines:(void (^)(NSString*))block completion:(void (^)())completion { if (self.queue == nil) { self.queue = [[NSOperationQueue alloc] init]; self.queue.maxConcurrentOperationCount = 1; } self.callback = block; self.completion = completion; self.inputStream = [NSInputStream inputStreamWithURL:self.fileURL]; self.inputStream.delegate = self; [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.inputStream open]; } ``` Now the input stream will send us delegate messages (on the main thread), and we do the processing on the operation queue by adding a block operation: ```objc - (void)stream:(NSStream*)stream handleEvent:(NSStreamEvent)eventCode { switch (eventCode) { ... case NSStreamEventHasBytesAvailable: { NSMutableData *buffer = [NSMutableData dataWithLength:4 * 1024]; NSUInteger length = [self.inputStream read:[buffer mutableBytes] maxLength:[buffer length]]; if (0 < length) { [buffer setLength:length]; __weak id weakSelf = self; [self.queue addOperationWithBlock:^{ [weakSelf processDataChunk:buffer]; }]; } break; } ... } } ``` Processing a data chunk looks at the current buffered data and appends the newly streamed chunk. It then breaks that into components, separated by newlines, and emits each line. The remainder gets stored again: ```objc - (void)processDataChunk:(NSMutableData *)buffer; { if (self.remainder != nil) { [self.remainder appendData:buffer]; } else { self.remainder = buffer; } [self.remainder obj_enumerateComponentsSeparatedBy:self.delimiter usingBlock:^(NSData* component, BOOL last) { if (!last) { [self emitLineWithData:component]; } else if (0 < [component length]) { self.remainder = [component mutableCopy]; } else { self.remainder = nil; } }]; } ``` If you run the sample app, you will see that the app stays very responsive, and the memory stays very low (in our test runs, the heap size stayed under 800 KB, regardless of the file size). For processing large files chunk by chunk, this technique is probably what you want. Further reading: * [File System Programming Guide: Techniques for Reading and Writing Files Without File Coordinators](http://developer.apple.com/library/ios/#documentation/FileManagement/Conceptual/FileSystemProgrammingGUide/TechniquesforReadingandWritingCustomFiles/TechniquesforReadingandWritingCustomFiles.html) * [StackOverflow: How to read data from NSFileHandle line by line?](http://stackoverflow.com/questions/3707427/how-to-read-data-from-nsfilehandle-line-by-line) ## Conclusion In the examples above we demonstrated how to perform common tasks asynchronously in the background. In all of these solutions, we tried to keep our code simple, because it's very easy to make mistakes with concurrent programming without noticing. Oftentimes you might get away with just doing your work on the main thread, and when you can, it'll make your life a lot easier. But if you find performance bottlenecks, put these tasks into the background using the simplest approach possible. The pattern we showed in the examples above is a safe choice for other tasks as well. Receive events or data on the main queue, then use a background operation queue to perform the actual work before getting back onto the main queue to deliver the results. [90]: /issues/2-concurrency/editorial/ [100]: /issues/2-concurrency/concurrency-apis-and-pitfalls/ [101]: /issues/2-concurrency/concurrency-apis-and-pitfalls/#challenges [102]: /issues/2-concurrency/concurrency-apis-and-pitfalls/#priority_inversion [103]: /issues/2-concurrency/concurrency-apis-and-pitfalls/#shared_resources [104]: /issues/2-concurrency/concurrency-apis-and-pitfalls/#dead_locks [200]: /issues/2-concurrency/common-background-practices/ [300]: /issues/2-concurrency/low-level-concurrency-apis/ [301]: /issues/2-concurrency/low-level-concurrency-apis/#async [302]: /issues/2-concurrency/low-level-concurrency-apis/#multiple-readers-single-writer [400]: /issues/2-concurrency/thread-safe-class-design/ ================================================ FILE: 2013-07-07-concurrency-apis-and-pitfalls.md ================================================ --- title: "Concurrent Programming: APIs and Challenges" category: "2" date: "2013-07-07 10:00:00" author: - name: Florian Kugler url: http://twitter.com/floriankugler tags: article --- [Concurrency](http://en.wikipedia.org/wiki/Concurrency_%28computer_science%29) describes the concept of running several tasks at the same time. This can either happen in a [time-shared](http://en.wikipedia.org/wiki/Preemption_%28computing%29) manner on a single CPU core, or truly in parallel if multiple CPU cores are available. OS X and iOS provide several different APIs to enable concurrent programming. Each of these APIs has different capabilities and limitations, making them suitable for different tasks. They also sit on very different levels of abstraction. We have the possibility to operate very close to the metal, but this also comes with great responsibility to get things right. Concurrent programming is a very difficult subject with many intricate problems and pitfalls, and it's easy to forget this while using APIs like Grand Central Dispatch or `NSOperationQueue`. This article will first give an overview of the different concurrency APIs on OS X and iOS, and then dive deeper into the inherent challenges of concurrent programming, which are independent of the specific API you use. ## Concurrency APIs on OS X and iOS Apple's mobile and desktop operating systems provide the same APIs for concurrent programming. In this article we are going to take a look at `pthread` and `NSThread`, Grand Central Dispatch, `NSOperationQueue`, and `NSRunLoop`. Technically, run loops are the odd ones out in this list, because they don't enable true parallelism. But they are related closely enough to the topic that it's worth having a closer look. We'll start with the lower-level APIs and move our way up to the higher-level ones. We chose this route because the higher-level APIs are built on top of the lower-level APIs. However, when choosing an API for your use case, you should consider them in the exact opposite order: choose the highest level abstraction that gets the job done and keep your concurrency model very simple. If you're wondering why we are so persistent recommending high-level abstractions and very simple concurrency code, you should read the second part of this article, [challenges of concurrent programming](#challenges-of-concurrent-programming), as well as [Peter Steinberger's thread safety article][400]. ### Threads [Threads](http://en.wikipedia.org/wiki/Thread_%28computing%29) are subunits of processes, which can be scheduled independently by the operating system scheduler. Virtually all concurrency APIs are built on top of threads under the hood -- that's true for both Grand Central Dispatch and operation queues. Multiple threads can be executed at the same time on a single CPU core (or at least perceived as at the same time). The operating system assigns small slices of computing time to each thread, so that it seems to the user as if multiple tasks are executed at the same time. If multiple CPU cores are available, then multiple threads can be executed truly in parallel, therefore lessening the total time needed for a certain workload. You can use the [CPU strategy view](http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/AnalysingCPUUsageinYourOSXApp/AnalysingCPUUsageinYourOSXApp.html) in Instruments to get some insight of how your code or the framework code you're using gets scheduled for execution on multiple CPU cores. The important thing to keep in mind is that you have no control over where and when your code gets scheduled, and when and for how long its execution will be paused in order for other tasks to take their turn. This kind of thread scheduling is a very powerful technique. However, it also comes with great complexity, which we will investigate later on. Leaving this complexity aside for a moment, you can either use the [POSIX thread](http://en.wikipedia.org/wiki/POSIX_Threads) API, or the Objective-C wrapper around this API, `NSThread`, to create your own threads. Here's a small sample that finds the minimum and maximum in a set of 1 million numbers using `pthread`. It spawns off 4 threads that run in parallel. It should be obvious from this example why you wouldn't want to use pthreads directly. ```objc #import