Migrating to modern Objective-C

iOS 7 SDK

Last year at WWDC 2012, Apple introduced Modern Objective-C alongside iOS 6. So what’s this? In a few words, it is a huge step forward to help developers write less code to achieve the same things. Worth mentioning is that modern Objective-C has nothing to do with iOS versions, it has to do with the compiler, which means that it is backward compatible.

Let’s dive into the basics of transitioning to modern Objective-C. Xcode offers a refactoring tool (edit>Refactor>Convert to Modern Objective-C syntax) which will convert your project to modern Objective-C (it will also set the appropriate flag in build settings). If you would like to adopt modern Objective-C when writing your code, which is the best, as it is intended to help you write less lines of code, general rules for doing so are the following.

Default property synthesis

Usually iOS developers declare a property in the header file and have to synthesize it in the implementation file in order to access it. With modern Objective-C there is no need to synthesize properties. All properties are synthesized automatically and you can access them using the property name prefixed with an underscore. For example you declare this property in your header (.h) file

@interface MyViewController : UIViewController

@property (strong, nonatomic) IBOutlet UILabel *myLabel;

@end

In the implementation file you can access your UILabel using:

_myLabel.text = @"Great, no need to synthesize properties";

NSNumber Literals

Up to now, initializing an NSNumber involved a considerable amount of typing and calling class methods to describe the value type you are going to put on that NSNumber. Typical examples are:

NSNumber *number1 = [NSNumber numberWithInt:154];
NSNumber *number2 = [NSNumber numberWithFloat:154.243f];
NSNumber *number3 = [NSNumber numberWithBool:YES];

In modern Objective-C, the above code looks just like this:

NSNumber *number1 = @154;
NSNumber *number2 = @154.243f;
NSNumber *number3 = @YES;

Array Literals

Working with NSArray objects is also simplified in modern Objective-C. The old way of initializing an NSArray was like the below sample code:

NSArray *cityArray;
cityArray = [[NSArray alloc] initWithObjects:@"Athens", @"Paris", @"London", @"Berlin", @"Oslo", nil];

Now we can just initialize an NSArray as follows:

NSArray *cityArray;
cityArray = @[@"Athens", @"Paris", @"London", @"Berlin", @"Oslo"];

Note that in modern Objective-C there is no need to nil terminate an NSArray object. Also when writing the above code, the compiler generates:

id objects[] = { @"Athens", @"Paris", @"London", @"Oslo" };
NSUInteger count = sizeof(objects) / sizeof(id);
cityArray = [NSArray arrayWithObjects:objects count:count];

The same shortening applies also when accessing an NSArray object. So instead of:

NSString *secondCity = [cityArray objectAtIndex:1];

we can now use just:

NSString *secondCity = cityArray[1];

Dictionary Literals

Initializing an NSDictionary object follows the same concept like NSArray literals. So usually we initialize an NSDictionary like that:

NSDictionary *cityListing = [NSDictionary dictionaryWithObjectsAndKeys: object1, key1, object2, key2, object3, key3, nil];

Up to now NSDictionaries needed to be nil terminated like NSArrays. In modern Objective-C the initialization is like the code snippet bellow. Note that now reading an NSDictionary initialization method is also match easier, thanks to the “:” separating each object with its key.

NSDictionary *cityListing = @{key1 : object1, key2 : object2, key3 : object3};

As with NSArrays, when writing this code, the compiler generates:

id objects[] = { object1, object2, object3 };
id keys[] = { key1, key2, key3 };

NSUInteger count = sizeof(objects) / sizeof(id);

cityListing = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:count];

Accessing values and objects of an NSDictionary is also simplified, so instead of:

NSString *city = [cityListing objectForKey:key1];

we just type:

NSString *city = cityListing[key1];

For a further look on modern Objective-C syntax, you can refer the llvm website here. As seen from these simple code snippets, a lot of common initializations and declarations get much simpler -and actually faster- with the new syntax. It is fair to say that the transition to modern Objective-C is the next big step after moving to ARC for iOS/Mac developers.

2 thoughts on “Migrating to modern Objective-C

Leave a Reply to Nikos M. Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.