Các class NSString, NSArray, NSNumber, NSDictionary thuộc Foundation framework. Chúng có cú pháp dài dòng giống như đặc trưng của ngôn ngữ Objective-C. Tuy nhiên, từ Objective-C 1.0 đã xuất hiện literal syntax giúp việc viết code ngắn gọn và dễ đọc hơn.
Không dùng literal syntax:
NSString *someString = [NSString stringWithFormat:@"some String"];
NSString *literalString = @"literal String";
Không dùng literal syntax:
NSNumber *someNumber = [NSNumber numberWithInt:1];
NSNumber *literalNumber = @1;
Không chỉ với kiểu dữ liệu int, literal syntax còn dùng với tất cả các kiểu khác mà NSNumber có thể đại diện.
NSNumber *intNumber = @1; NSNumber *floatNumber = @1.0f; NSNumber *doubleNumber = @3.14217; NSNumber *boolNumber = @YES; NSNumber *charNumber = @'a';
Literal syntax còn dùng được với một expression:
int x = 2; int y = 3.14; NSNumber *expressionNumber = @(x * y);
Không dùng Literal syntax:
NSArray *animals = [NSArray arrayWithObjects:@"cats", @"dog", @"mouse", @"bird", nil];
NSArray *animals = @[@"cats", @"dog", @"mouse", @"bird"];
Không chỉ khởi tạo array, việc lấy ra phần tử của NSArray với literal syntax (subscripting) cũng ngắn gọn hơn:
Không dùng Literal syntax:
NSString *dog = [animals objectAtIndex:1]
NSString *dog = animals[1];
Lưu ý, khi tạo NSArray bằng cách sử dụng literal syntax, nếu một phần tử bằng nil, một exception như sau sẽ bị xổ ra:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1]'
Điều này dẫn đến một vấn đề nhỏ khi sử dụng literal syntax. Ví dụ:
NSString *string1 = @"string1"; NSString *string2 = nil; NSString *string3 = @"string3"; NSArray *arrayA = [NSArray arrayWithObjects:string1, string2, string3, nil]; NSArray *arrayB = @[string1,string2,string3];
Trong trường hợp này, arrayB sẽ khiến exception bị xổ ra do có phần từ nil trong mảng, arrayA vẫn sẽ được tạo và sẽ chỉ có một phần tử là string1 do hàm mà arrayA dùng để khởi tạo sẽ dừng khi nó bắt gặp nil nhưng do string2 là nil nên nó dừng sớm hơn dự kiến ban đầu.
Sự khác nhau ở trên có nghĩa là literal syntax an toàn hơn trong việc khởi tạo mảng do nó bắn ra exception khi có phần tử nil trong mảng còn hơn là việc tạo ra mảng mà có ít phần tử hơn dự kiến. Exception được bắn ra sẽ giúp tìm ra lỗi dễ dàng hơn.
Không dùng literal syntax:
NSDictionary *personData = [NSDictionary dictionaryWithObjectsAndKeys: @"Tuan Hai", @"firstName", @"Tran", @"lastName", [NSNumber numberWithInt:24], @"age", nil];
Nhìn khá loạn, do thứ tự value-key của cách này. Sử dụng literal syntax:
NSDictionary *personData = @{@"firstName" : @"Tuan Hai", @"lastName" : @"Tran", @"age" : @24};
Rõ ràng, dùng literal syntax ngắn gọn hơn và cũng giống với cách ta thường nghĩ về NSDictionary đó là key-value. Tương tự NSArray, NSDictionary cũng xổ ra exception khi có phần tử nil trong lúc khởi tạo bằng literal syntax.
Cũng giống như NSArray, NSDictionary có thể được truy cập bằng literal syntax. Cách cũ:
NSString *firstName = [personData objectForKey:@"firstName"];
NSString *firstName = personData[@"firstName"];
NSMutableArray và NSMutableDictionary
Giống cách truy cập các phần tử bằng index trong NSArray hay key trong NSDictionary, ta có thể set giá trị của nó nếu object là mutable. Cách cũ:
[mutableArray replaceObjectAtIndex:1 withObject:@"dog"]; [mutableDictionary setObject: @"Tuan Hai" forKey:@"firstName"];
mutableArray[1] = @"dog" mutableDictionary[@"firstName"] = @"Tuan Hai";
Khi tạo một mutable object bằng literal syntax, cần phải gọi thêm hàm mutableCopy:
NSMutableArray *mutableArray = [@[@1, @2, @3] mutableCopy];
Tuy phải gọi thêm một lời gọi hàm nhưng lợi ích của việc dùng literal syntax lớn hơn hạn chế này.
Sử dụng literal syntax để khởi tạo string, array, number, dictionary vì cú pháp ngắn gọn, rõ ràng.
Truy cập phần tử của array và dictionary bằng subscript
Đảm bảo không có phần tử nil được thêm vào array và dictionary khi sử dụng literal syntax.