The Basics of Modern Objective-C

From Techotopia
Revision as of 14:51, 19 September 2012 by Neil (Talk | contribs) (New page: The preceding two chapters have provided an introduction to Objective-C for readers that are new to the language. This chapter is intended for those programmers familiar with Objective-C 2...)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The preceding two chapters have provided an introduction to Objective-C for readers that are new to the language. This chapter is intended for those programmers familiar with Objective-C 2.0 who would like to get a quick overview of some of the new features added to the language to coincide with the release of the iOS 6 SDK. These changes have combined to create what, for want of a better description, has come to be referred to as “Modern Objective-C”

Whilst an in-depth analysis of all the changes in Modern Objective-C is beyond the scope of this book, it is intended that this chapter will cover some key features that will make your life easier as an iOS developer.


Contents


Default Property Synthesis

Experienced iOS developers will be intimately familiar with the concept of declaring a property in an interface file and then having to synthesize that property within the implementation file. Consider, for example, the following typical interface file for a class in an iOS application:

@interface AudioViewController : UIViewController
   <AVAudioPlayerDelegate>

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;
@property (strong, nonatomic) IBOutlet UISlider *volumeControl;
@end

Prior to the changes in Modern Objective-C, the above properties would have required matching @synthesize directives in the corresponding implementation file in order to be accessible from within the implementation code:

#import "AudioViewController.h"

@interface AudioViewController ()

@end

@implementation AudioViewController
@synthesize audioPlayer = _ audioPlayer;
@synthesize volumeControl = _volumeControl;
.
.
.
@end

In the case of Modern Objective-C, however, the synthesis takes place by default, making the use of @synthesize declarations unnecessary:

#import "AudioViewController.h"

@interface AudioViewController ()

@end

@implementation AudioViewController
.
.
.
@end 

When using default property synthesis, instance variable properties are accessible from within code using the property name prefixed with an underscore. For example, the following code accesses the previously declared volumeControl property:

#import "AudioViewController.h"

@interface AudioViewController ()

@end

@implementation AudioViewController
.
.
.
- (void)enableVolume {
    _volumeControl.enable = YES;
}
@end

Method Ordering

Method ordering refers to the positions in which methods are declared within an Objective-C source file. In previous versions of the language, a method had to be declared above any points in the code file from which it was called. Placing a method after a location where it was called resulted in a compilation error.

Historically, the following code would result in a compilation error stating that the method named flushBuffer could not be found:

@implementation DatabaseHandler

- (void)closeDatabaseFile {
	[self flushBuffer];
}

- (void)flushBuffer {
    // Code here to flush buffer
}

With Modern Objective-C the ordering of methods is no longer an issue and the above code will compile without any errors.


NSNumber Literals

Up until the introduction of Modern Objective-C, the initialization of NSNumber objects required calling class methods and, consequently, a considerable amount of typing for what was really a very basic coding task. For the sake of an example, consider the code to initialize an NSNumber object with an integer value:

NSNumber *number = [NSNumber numberWithInt:512];

With Modern Objective-C, the same result can be achieved with the following, much simpler, line of code:

NSNumber *number = @512;

Similarly, consider the code to initialize an NSNumber instance with a floating point number:

NSNumber *number = [NSNumber numberWithFloat:512.123f];

The above code can now be replaced with the following:

NSNumber *number = @512.123f;

In fact, all the numberWith<type> methods of the NSNumber class can now be replaced with literals when using Modern Objective-C:

NSNumber *number;

number = @’A’; // Character
number = @YES; // Boolean
number = @43231ul // Unsigned Long
number = @123431ll // Long Long
number = @1254.23 // Float
number = @123 // Integer
number = @123.432 // Double

Array Literals

Modern Objective-C also considerably simplifies the task of working with NSArray objects. With array literals, the initialization of an NSArray now involves considerably less typing and finished code that is easier to read.

The following code fragment demonstrates the old way of initializing an NSArray object:

NSArray *carMakes;

carMakes = [[NSArray alloc]
                     initWithObjects:@"Chevy",
                     @"BMW",
                     @"Toyota",
                     @"Volvo",
                     @"Smart", nil]; 

Using array literals, the above code can now be replaced with the following simpler syntax:

NSArray *carMakes;

carMakes = @[@"Chevy", @"BMW", @"Toyota", @"Volvo", @"Smart"];

Similarly, accessing array elements now requires less typing. For example, the following code used to be required to access element 0 of an array:

NSString *firstCar = [carMakes objectAtIndex:0];

With Modern Objective-C, this can be shortened to the following syntax:

NSString *firstCar = carMakes[0];

This new syntax uses a programming construct referred to as index subscripting and will be familiar to those who have used other programming languages such as Java, C, C++ or C#.

Similarly, the same index subscripting syntax can be used when setting array elements. For example, the following line of code assigns a new string to the second element of the array:

carMakes[1] = @”VW Jetta”;

Note that the literal syntax creates immutable arrays by default. If a mutable array is required when using this syntax, the mutableCopy method of the object must be called. For example:

NSMutableArray *carMakes = [@[@"Chevy", @"BMW", @"Toyota", @"Volvo", @"Smart"] mutableCopy];

Dictionary Literals

Modern Objective-C brings a similar approach to managing NSDictionary objects. Using classic Objective-C syntax, an NSDictionary object would typically be initialized with multiple key-value pairs using the following syntax:

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

With Modern Objective-C, however, this same code can be simplified using the following, easier to read syntax:

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

As with arrays, subscripting may be used when referencing dictionary items. The following code, for example, extracts the object for “key1” from the bookListing dictionary using keyed subscripting:

bookObject = bookListing[key1];

Similarly, the following code replaces the object associated with “key2” in the dictionary with the object referenced by newBookObject:

bookListing[key2] = newBookObject;

As is the case with arrays, dictionary objects created using this literal syntax are immutable by default.

Summary

The Objective-C compiler version that accompanies the iOS 6 SDK includes a number of improvements designed to make code easier to read and to minimize the amount of typing required by the programmer. This chapter has covered some of the key features added to what is referred to as Modern Objective-C. Where appropriate, the code examples in the remainder of this book will use Modern Objective-C syntax.