很多剛從其他編程語言轉到Objective-C的程序員,往往看到長長的函數名就會覺得感到崩潰,這種語法讓消息的傳遞像一個英語句子,雖有不足但確實大大增強了可讀性。比如想初始化一個浮點數,需要這么寫:
NSNumber * value = [NSNumber numberWithFloat:123.45f];
從這句中能夠明確的知道代碼的含義,但是,是否連簡單的賦值語句都需要這么處理呢?對象的字面量,能夠幫助iOS程序員更加高效的編寫代碼。在Xcode4.4版本中,這個特性已經可以使用了。
對象的字面量語序方便的定義數字,數組和字典對象。這個功能類似于Java 5提供的auto boxing功能。這雖然是一個語法改進,但是對提高寫代碼的效率有很大的幫助。蘋果本次的新特性中采用了折中的處理方式,針對很對基礎類型,采用了簡寫的方式,實現語法簡化。簡化以后,會發現語法層面上,簡化的OC更像Python和Ruby等動態語言的語法了。
NSNumber * number = @1;
NSArray * array = @[@"one",@"two"];
NSDictionary * dict = @{@"key1": @"value1",@"key2",@"value2",@"key3",@"value3"};
下面逐一介紹
1.數字(NSNumber)
簡化后的寫法:
NSNumber * value;
value = @12345;
value = @123.45f;
value = @123.45;
value = @YES;
裝箱表達式也可以采用類似的寫法:
NSNumber * piOverSixteen = @(M_PI / 16);
NSString * path = @(getenv("PATH"));
對于字符串表達式來說,需要注意的是,表達式的值一定不能是NULL,否則會拋出異常。
2.數組(NSArray)
對于NSArray的初始化來說,有非常多的寫法,這里就不一一羅列,直接看新的寫法。
NSArray * array;
array = @[];//空數組
array = @ [ a ];//一個對象的數組
array = @[a,b,c];//多個對象的數組
非常簡單,再也不用記住初始化多個對象的數組時,后面還要跟個nil。仙子看一下你當生命多個對象的數組時,編譯器是如何處理的。
array = @[a,b,c];
編譯器生成的代碼:
id objects[] = {a,b,c};
NSUInterger count = sizeof(objects) /sizeof(id);
array = [NSArray arrayWithObjects:objects count:count];
編譯器把簡單重復的工作都做了,不過有一點需要注意,如果a,b,c對象有nil的時候,會拋出異常,這點和原來的處理方式不能,編碼時候要多加小心。
3.字典(NSDictionary)
同樣,對于字典這個數據結構來說,有很多種初始化方式,來看新寫法。
NSDictionary * dict;
dict = @{};
dict = @{ k1 : o1};
dict = @{k1:o1,k2:o2,k3:o3};
4.下標法與容器類
容器的語法簡化讓人不難想到,可以通過下標的方式存取數組和字典的數據。比如對于數組:
NSArray * array = @[a,b,c];
可以這樣寫:
id obj = array[i];
array[i] = newObj;
對于字典:
id obj = dict[k2];
dic[k2] = newObj;
同時,自定義的容器類只要實現規定的下標方法,就可以采用下標的方式訪問數據。要實現的方法如下。
數組類型的下標方法:
- (elementType)objectAtIndexedSubscript:(indexType)idx;
- (void)setObject:(elementType)object atIndexedSubscript:(indexType)idx;
字典類型的下標方法:
- (elementType)objectForKeyedSubscript:(keyType)key;
- (void)setObject:(elementType)object forKeyedSubscript:(keyType)key;
其中需要注意的是,indexType必須是整數,elementType和keyType必須是對象指針。
5.容器類數據結構轉換限制
采用上述寫法構建的容器類都是不可變的,如果需要生成可變的容器,可以傳遞-mutable Copy消息。例如:
NSMutableArray * mutablePlanets = [@[@"Mercury",@"Venus",@"Earth",@"Mars",@"Jupiter",@"Saturn",@"Uranus",@"Neptune"]mutableCopy];
不能對常量數組直接賦值,解決辦法是在類方法(void)initialize中進行賦值處理。如下:
@implementation MyClass
static NSArray * thePlanets;
+ (void)initialize {
if (self == [MyClass class]) {
thePlanets = @[@""Mercury",@"Venus",@"Earth",@"Mars",@"Jupiter",@"Saturn",@"Uranus",@"Neptune""];
}
}}
要點###
(1)盡量使用字面量語法來創建字符串,數字,數組和字典等,使用它比使用以前常規對象創建方法更為精簡,同時可以避免一些常見的陷阱。
(2)對象字面量語法特性是完全可以向下兼容的,使用新特性編寫出來的代碼,經過編譯后形成的二進制程序可以運行在之前發的任何OS中。
(3)在數字和字典中,要使用關鍵字和索引做下標來獲取數據。
(4)使用對象字面量語法時,容器類的不可是nil,否則運行的時候會拋出異常。