Skip to content

standard iOS patterns

sebastienwindal edited this page Dec 6, 2012 · 46 revisions

A common problem we often experience when developing iOS applications or any kind of applications for that matter, is how to allow communication between application components, without the need to have excessive coupling. In the typical iOS application we need ways for objects to “notify” other object of the occurrence of certain events, or ways for objects to provide other objects with certain information, while keeping all those objects as self contained as possible.

iOS natural UI architecture is MVC (Model, View, Controller). That pattern splits the application in 3 classes of components:

  • model objects (application persistent data, backend service, business rules, etc...).
  • view objects (the UI elements the user sees and interact with).
  • view controller objects (objects that tie everything together).

Furthermore, it is good practice to split each part/functionality of the application into multiple modules/components (every one of them consisting of multiple MVC pieces), to achieve reusability, maintainability and to facilitate team work.

To sum up we need:

  • models <-> View controllers communication
  • View controllers <-> views communication
  • View Controllers <-> View Controllers communication
  • models <-> models communication (?)

While there are many different techniques to tackle those problems, it makes sense when working on any platform and framework to embrace the philosophy and spirit of that framework and to adopt the patterns that it is using, especially when that framework is as solid, well designed and proven as Cocoa (born in the 1990s at NeXT and still running strong)...

We are going to cover five (actually more like 4.5) of the most common patterns you will encounter in iOS development:

  • Delegation
  • [Key Value Observing](Key Value Observing)
  • NSNotification
  • [Callback handlers using selectors](Callback handlers using selectors)
  • [Callback handlers using blocks](Callback handlers using blocks)

Because those patterns are widely used throughout the cocoa framework, we have at our disposition many helper objects as well as unique objective-C features that will make their implementation relatively straightforward, if not easy.

Interesting slides from the first lesson of the highly recommended Stanford iOS class (available on iTunesU):

MVC pattern MVC pattern MVC pattern

I am writing this mostly form my own experience and opinion. For a lot more patterns stuff and to get it directly from the source, I recommend reading apple document about Cocoa design patterns.

Our demo use case

We have an object (BigCalculator) that performs a complex and lengthy operation on a background thread. The operation is started by calling the startBigCalculationWithNumber:andNumber: method. We have a view controller that is starting the calculation and that wants to be notified of the operation progress, completion and final result.

I have implemented this scenario 5 times to illustrate those 5 techniques and patterns and for ease of comparison. Keep in mind however that not all of them make sense for that particular use case. Using NSNotification here for instance certainly feels like using a bazooka to kill a fly. The Xcode project consists of 5 folders each one with a BigCalculator object and a view controller. The storyboard file contains the 5 similar views with an additional launcher view.

Comparison matrixes

Use case/Pattern Delegation KVO NSNotification Callbacks
View -> ViewController EXCELLENT VERY BAD VERY BAD EXCELLENT
Child View Controller -> Parent VC EXCELLENT VERY BAD MAYBE GREAT
Model -> View Controller GREAT GREAT GREAT EXCELLENT
Model -> Model GREAT MAYBE MAYBE EXCELLENT
View -> Model NO! NO! NO! NO!
View -> View NO! NO! NO! NO!

Implementation complexity

Pattern notified object object notifying
delegation low low
KVO medium none to high
NSNotification medium low
Callbacks using nsinvocation low highest
Callbacks using block low high