Skip to content
jverkoey edited this page Jun 5, 2012 · 13 revisions

For a broader overview on best practices, see Jeff's iOS Best Practices article on Github.

Memory Management

How to implement property setters

We generally use the following model for implementing copy/retain setters for properties in Nimbus:

- (void)setSomeProperty:(id)someProperty {
  if (_someProperty != someProperty) {
    [_someProperty release];
    _someProperty = [someProperty retain]; // or copy

    // Deal with the changed property.
  }
}

An example of what is not ok:

- (void)setSomeProperty:(id)someProperty {
  [_someProperty release];
  _someProperty = [someProperty retain]; // or copy

  // Deal with the changed property.
}

This example introduces a subtle bug when setSomeProperty: is called with _someProperty. Assume that _someProperty is only retained by this object, giving it a retain count of 1. If we call setSomeProperty: with a pointer equivalent to _someProperty then _someProperty will be released and immediately deallocated. When we then go to retain someProperty in the next line the method will crash because someProperty == _someProperty and _someProperty has been deallocated.

Another solution to this problem is to use the autorelease/retain pattern. This is also accepted, though we generally prefer the if not equal, release/retain pattern because it encourages logic being executed only if a change occurs.

NSObject

-(void)description Implementation

The description method is a valuable debugging tool. Implementing the description method allows an object to present more than just its class name and pointer address.

When implementing the method, the goal is to make modification to the method as easy as possible. This means it should be easy to add new parameters or remove existing ones. In order to encourage this, we implement the description method as follows:

- (NSString *)description {
  return [NSString stringWithFormat:
          @"<%@"
          @" objectId: %@"
          @", name: '%@'"
          @", information: '%@'"
          @">",
          [super description],
          self.objectId,
          self.name,
          self.information];
}

Note that each property has the format @", <property-name>: <property-value>". This makes it easy to simply delete two rows from the method to remove a property. To add a property, we simply copy any line and replace the correct parts.

UIViewController

NIIsSupportedOrientation and shouldAutorotateToInterfaceOrientation:

Use NIIsSupportedOrientation to implement shouldAutorotateToInterfaceOrientation:. NIIsSupportedOrientation will disallow upside-down portrait on the iPhone and allow all orientations on the iPad.

Example

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
  return NIIsSupportedOrientation(toInterfaceOrientation);
}