Objective-C以復雜的語法著稱,事實上確實是這樣.不過從Objective-C1.0開始,有一個非常簡單的方式創(chuàng)建NSString對象,那就是"字符串字面量",其語法如下:
NSString *str = @"Objective-C is the best programming language";
當然不用這樣的語法的話,就要用常見的alloc及init方法來分配并初始化NSString對象了.在新版的編譯器中,也能用這種字面量語法來聲明NSNumber, NSArray, NSDictionary類的實例.使用字面量語法(literal syntax)可以縮減源代碼的長度,使其可讀性提高.
字面數(shù)值
整數(shù), 浮點數(shù), 布爾值封入Objective-C對象中.這種情況下,可以使用NSNumber類.
一般做法:
NSNumber *num = [NSNumber numberWithInt:3];
字面量語法:
NSNumber *num = @1;
可以看到,字面量語法更為簡潔.不過它的好處還遠不止這些,能以NSNumber實例表示的所有數(shù)據(jù)類型都可以使用該語法,例如:
NSNumber *intNum = @3;
NSNumber *floatNum = @3.3f;
NSNumber *doubleNum = @3.33333;
NSNumber *boolNum = @YES;
NSNumber *charNum = @'a';
同時字面量語法也適用于表達式:
int a = 3;
float b = 3.33f;
NSNumber *expressionNum = @(a * b);
用字面量來表示數(shù)值十分有用,這樣做可以使NSNumber更為簡潔,以為其中只有數(shù)字,沒有其他多余成分.
字面量數(shù)組
數(shù)組是常用的數(shù)據(jù)結構,通常創(chuàng)建一個數(shù)組的方法是:
NSArray *array = [NSArray arrayWithObjects:@"one", @"two", @"three"];
而使用字面量語法來創(chuàng)建則是:
NSArray *array = @[@"one", @"two", @"three"];
這種做法不僅簡單,而且還有利于操作數(shù)組,數(shù)組最常見的操作就是通過某個下標取得對應的對象,如果不適用"字面量語法",通常的做法是:
NSString *string = [array objectAtIndex:0];
適用字面量語法的做法則是:
NSString *string = array[0];
這樣的做法簡單明了,更容易理解.也和其他語言中訪問數(shù)組中的某個元素類似.
注意:
使用字面量語法創(chuàng)建數(shù)組時,若數(shù)組元素對象中有nil,則會拋出異常.因為字面量語法其實是一種"語法糖"(計算機語言中與另外一套語法等效但是開發(fā)者使用起來更加方便的語法,語法糖可以使程序的可讀性提高,同時減少代碼出錯率).其效果等于先創(chuàng)建了一個數(shù)組,然后把方括號中的所有對象都加到這個數(shù)組中.
舉個例子:
id object1 = /* ... */;
id object2 = /* ... */;
id object3 = /* ... */;
NSArray *arrayA = [NSArray arrayWithObjects:object1, object2, object3];
NSArray *arrayB = @[object1, object2, object3];
不妨思考一下:如果object1和object3都指向了有效的Objective-C對象,而object2是nil,會出現(xiàn)什么情況?如果采用字面量語法,創(chuàng)建arrayB時會拋出異常(attempt to insert nil object from arrayB[1]),arrayA雖然能創(chuàng)建成功,但是其中只有一個object1對象,原因很簡單:arrayWithObjects:方法會依次處理每個參數(shù),直到發(fā)現(xiàn)nil為止.
這個差別表明:使用字面量語法更為安全.拋出異常令程序終止,這比創(chuàng)建好數(shù)組發(fā)現(xiàn)數(shù)組中元素個數(shù)不對要好很多.想數(shù)組中插入nil通常說明程序有錯,通過異称饕福可以更快的找個這個錯誤.
字面量字典
"字典"是一種映射型數(shù)據(jù)結構,可向其中添加鍵值對.OC中通常創(chuàng)建字典的做法是:
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
@"Country" ,@"firstName",
@"Gene", @"lastName",
@[NSNumber numberWitnInt:18], @"age", nil];
這樣寫令代碼的可讀性不高,因為順序是<對象>, <鍵>.這與通常的理解剛好相反.我們一般理解為"鍵"映射到"對象".然而使用字面量語法:
NSDictionary *dictionary = @{@"firstName" : @"Country",
@"lastName" : @"Gene"
@"age" : @18};
這樣寫的好處一目了然.代碼可讀性還高.同時還指明:字典中的對象和建都必須是OC對象,所以不能把18直接放到字典中.
同樣用字面量語法創(chuàng)建字典也有一個問題,那就是一旦有值為nil,程序便會拋出異常.這樣也恰到好處提醒了程序猿們字典中有了空對象.同理"dictionaryWithObjectsAndKeys"則無法做到這一點.
還有一點就是通過鍵值來訪問其值,通常的做法:
NSString *name = [dictionary objectForKey:@"firstName"];
與之等效的字面量語法是:
NSString *name = dictionary[@"firstName"];
可變數(shù)組和字典
對于可變的數(shù)組和字典,字面量語法不僅能訪問到數(shù)組中某個下標對應的元素或字典中某個鍵對應的元素,還可以通過下標修改對應元素的值.
標準做法:
[mutableArray replaceObjectAtIndex:0 withObject:@"Ben"];
[mutableDictionary setObject:@"Ben" forKey:@"lastName"];
字面量語法:
mutableArray[0] = @"Ben";
mutableDictionary[@"lastName"] = @"Ben";
好處不言自明!
局限性
俗話說:金無足赤,人無完人.除了字符串以外,所創(chuàng)建出來的對象必須屬于Foundation框架才行.如果自定義了這些類的子類,則無法使用字面量語法了.要想創(chuàng)建自定義子類的實例,必須采用"非字面量語法".不過也不建議這么做.因為NSArray, NSDictionary, NSNumber都是業(yè)已定型的"子族",很少有人會從其中自定義子類.真要這么做也比較麻煩.
使用字面量語法創(chuàng)建出來的字符串,數(shù)組,字典對象是不可變的.若想變成可變版本,需要復制一份.
NSMutableArray *mutableArray = [@[@1, @2, @3] mutableCopy];
這么做會多調用一個方法,而且還有再創(chuàng)建一個對象,不過筆者認為"功大于過"!
總結:
- 應該使用字面量語法來創(chuàng)建字符串, 數(shù)組, 數(shù)值, 字典.與創(chuàng)建此類對象的常規(guī)方法相比這么做更簡潔明了.
- 應該通過取下標操作來訪問數(shù)組下標或字典中鍵所對應的元素.
- 用字面量語法創(chuàng)建數(shù)組或字典時,若值為nil, 則會拋出異常, 因此, 務必確保值里不包含nil.