Advertisement

Objective-C Literals

by

This tutorial will teach you how to program more efficiently using object literals!


Literals & Literal Expressions

In programming, a literal is simply a fixed value that a programmer enters into a source code file. A few examples from C include:

int year = 2012;
char initial = 'M';

In the above, '2012' is an int literal and 'M' is a char literal.

Computer Scientists also sometimes refer to literal expressions. An expression is simply a group of values and operators that return a new value, such as "2 * pi * r". A literal expression is an expression that only contains literal values, such as "2 * 3.14 * 10".

The following code snippet demonstrates how variables can be created and assigned with literal expressions in C:

int result = 15 / 5;  // The literal expression "15 / 5" yields 3
double = 5 / 2;       // The literal expression "5 / 2" yields 2.5

Because Objective-C is a superset of C, all of the lines of code demonstrated in C so far are also valid Objective-C syntax. However, all of the literals demonstrated have also been for primitive data types. A more interesting use of literals is to apply them to objects.

The following is an example of an object literal:

NSString *siteTitle = @"Mobiletuts+";

In the above line of code, @"Mobiletuts+" is an object literal that is used to represent a string object. Without the use of an object literal, the above line of code would need to be written very differently, perhaps like this:

NSString *siteTitle = [NSString stringWithUTF8String:"Mobiletuts"];

As you can see, the object literal syntax is much more concise and readable.

With the release of the Apple LLVM Compiler 4.0, additional object literal support has been added for NSNumber objects, Array objects, and Dictionary objects.


NSNumber Literals

NSNumber objects can now be represented with object literals.

The following code snippet illustrates the traditional style:

NSNumber *boolYES = [NSNumber numberWithBool:YES];
NSNumber *boolNO  = [NSNumber numberWithBool:NO];
    
NSNumber *charX = [NSNumber numberWithChar:'X'];
    
NSNumber *fortySevenInt = [NSNumber numberWithInt:47];
NSNumber *fortySevenUnsigned = [NSNumber numberWithUnsignedInt:47U];
NSNumber *fortySevenLong = [NSNumber numberWithLong:47L];
    
NSNumber *goldenRatioFloat = [NSNumber numberWithFloat:1.61803F];
NSNumber *goldenRatioDouble = [NSNumber numberWithDouble:1.61803];

Using object literals, the above can be rewritten as simply:

NSNumber *boolYES = @YES;
NSNumber *boolNO  = @NO;
    
NSNumber *charX = @'X';
    
NSNumber *fortySevenInt = @47;
NSNumber *fortySevenUnsigned = @47U;
NSNumber *fortySevenLong = @47L;
    
NSNumber *goldenRatioFloat = @1.61803F;
NSNumber *goldenRatioDouble = @1.61803;

Objective-C Collection Literals

Collection literals are an incredibly useful addition to Objective-C. The new LLVM Compiler provides the ability for creating collection literals for both arrays and dictionaries, but not sets.

NSArray Literals

The old syntax for creating an NSArray:

    NSArray *instruments = [NSArray
                            arrayWithObjects: @"Ocarina", @"Flute", @"Harp", nil];

The new, object literal syntax for creating an NSArray:

NSArray *instruments = @[ @"Ocarina", @"Flute", @"Harp" ];

Unfortunately, the above syntax won't work for declaring an NSMutableArray, but there is an easy work around. Just pass the mutableCopy message to the newly formed object:

NSMutableArray *instrumentsMutable = [ @[ @"Ocarina", @"Flute", @"Harp" ] mutableCopy];

Dictionary Literals

The traditional method for creating a dictionary with Objective-C looks something like this:

NSArray *keys   = [NSArray arrayWithObjects:@"Character", @"Weapon", @"Hitpoints", nil];
NSArray *objects = [NSArray arrayWithObjects:@"Zelda", @"Sword", [NSNumber numberWithInt:50], nil];
NSDictionary *stats = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

Or, a slightly less verbose alternative:

NSDictionary *stats = [NSDictionary dictionaryWithObjectsAndKeys:
                           @"Zelda", @"Character",
                           @"Sword", @"Weapon",
                           [NSNumber numberWithInt:50], @"Hitpoints",
                           nil];

Both of the above are prime examples for why Objective-C has developed a bad reputation for being excessively verbose. No more! With object literals, the above code can be rewritten as simply:

NSDictionary *stats = @{ @"Character" : @"Zelda",
                         @"Weapon" : @"Sword",
                         @"Hitpoints" : @50 };

This is much easier to both understand and write.

Collection Subscripting

In addition to being able to create collections with object literals, the latest LLVM Compiler has also introduced support for accessing array or dictionary values with subscripts.

For example, this is the traditional form used for accessing an object from an array or dictionary:


NSString *instrument = [instruments objectAtIndex:0]; // Returns 'Ocarina' 

NSString *name = [stats objectForKey:@"Character"]; // Returns 'Zelda'

With the new, subscripting capability you can just do this:


NSString *instrument = instruments[0]; // Returns 'Ocarina'

NSString *name = stats[@"Character"]; // Returns 'Zelda'

Better still, collection subscripts aren't just limited to selecting objects. If the collection is mutable, you can also reassign values:


instrumentsMutable[0] = @"Ocarina of Time";

statsMutable[@"Weapon"] = @"Hammer";

This is a huge step forward for Objective-C programmers, and I think it will make the language more accessible to those transitioning from other languages like Java or C++ as well.


Boxed Expressions

The final topic worth mentioning in this tutorial is the concept of "Boxed Expressions". Essentially, Objective-C now supports converting the result of a C-style expression into an Objective-C object. The basic syntax for this is like so:

@( 2 * pi * r)

The result of the above would be an NSNumber object that contained the product of 2 times the value of pi times the value of r. We could, of course, immediately assign that product into an NSNumber variable:

NSNumber *diameter = @( 2 * pi * r );

This technique will work with enums and strings as well:


// Boxed Expressions with Enums
typedef enum { Sword, Hammer, Shield, Arrow } Weapons;
NSNumber *currentWeapon = @( Sword ); // Returns 0


// Boxed Expressions with char *
NSString *login = @( getlogin() ); // Returns login name


// Results
NSLog(@"Weapon: %@\nLogin: %@", currentWeapon, login);

Wrap Up

This tutorial has provided you with a quick overview of object literals, a new technique introduced with the Apple LLVM Compiler 4.0. For more in-depth coverage of this topic, refer to the official LLVM documentation.

I hope you enjoyed reading this tutorial. Feel free to leave any feedback you have in the comments section below. You can also connect with me on Twitter or Google Plus. Cheers!

Advertisement