Objective-C Subscripting

Subscripting is a new compiler feature which is introduced in Xcode 4.5 Subscripting provides a way to use subscripting with Arrays and Dictionaries. In general, subscripting make the source code look more cleaner. Let's take a look at some examples. First create an array with some values using String Literals.

NSMutableArray *names = [@ [@"Alex Smith", @"John Williams" , @"Joe Johnson"] mutableCopy]; 
NSInteger index = 1;

Originally we grab a value out of the array with the following syntax

NSString *myName = [names ObjectAtIndex:index]; // myName = @"John Williams"

With subscripting the code wil be

NSString *myName = names[index];

Ok, now insert a new value in the array without subscripting

[names insertObject:@"Jack Jones" atIndex:index];

And with subscripting

names[index] = @"Jack Jones";

Let's take a look at Dictionaries. First we create a dictionary

NSDictionary *nameDictionary = [@{ @"Alex" : firstName, @"Smith" : lastName} mutableCopy];

Originally we grab a value out of the dictionary with the following syntax

NSString *myFirstName = [namesDictionary objectForKey:firstName]; // myFirstName = "Alex"

With subscripting this will be

NSString *myFirstName = namesDictionary[firstName];

Insert a new value in the dictionary without subscripting

[namesDictionary setObject:@"United States" forKey:country];

and with subscripting

namesDictionary[country] = @"United States";

Object Subscripting

Object Subscribting is also a new compiler feature to make it possible to subscript your own objects. If you want to add an indexed-style subscripting to an object declare the following methods to the @interface section.

@interface Name : NSObject

@property (nonatomic, strong) NSMutableArray *name

- (id)objectAtIndexedSubscript:(NSUInteger)index; //getter
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)index; //setter

@end

The implementation section will be

@implementation Name

-(id) init
{
self = [self init]
if (self} {
_name = [[NSMutableArray alloc] init];
}

return self;
}

- (id)objectAtIndexedSubscript:(NSUInteger)index
{
return _name[index];
}

- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)index {
_name[index] = obj;
}

@end

Now you can use subscripting like this

Name *myName = [[MyName alloc] init]; 
myName[0] = @"Rick Smith";
NSLog(@"%@," myName[0]; // Returns "Rick Smith"

If you want to use keyed-style subscripting to an object you can use it like this

[objc]@interface FullName : NSObject

@property (nonatomic,strong) NSMutableDictionary *fullName;

- (id)objectForKeyedSubscript:(id)key; //getter
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key; //setter

@end

@implementation FullName

-(id) init
{
self = [self init];
if (self) {
_fullName = [[NSMutableDictionary alloc] init];
}

return self;
}

- (id)objectForKeyedSubscript:(id)key
{
return _fullNames[key];
}

- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key {
_fullName[key] = obj;
}

@end

Now you can use subscripting like this

 

FullName *myFullName = [[FullName alloc] init];
myFullName[@"lastName"] = @"Johnson";
NSLog(@"%@," myFullName[@"lastname"]; // Returns "Johnson"

As you can see subscripting makes your code much simpler. Also subscripting is backwords compatible with previous iOS versions.