身為一個(gè)Coder垄琐,自己已擁有的工具蹦肴,需要挖掘它們的潛力赶袄,本篇來系統(tǒng)梳理下字面量這個(gè)容易被忽略的OC語法工具揽涮。
字面量這個(gè)詞似乎挺陌生,但是下面的代碼你一定用過:
NSLog(@"Hello world");
這里@包含的就是一個(gè)字符串的字面量饿肺,如果不用字面量蒋困,你就需要這樣寫:
NSString *str = [[NSString alloc] initWithCString:"Hello world" encoding:NSUTF8StringEncoding];
NSLog(@"%@", str);
繁瑣不說,還很不直觀敬辣。有些教程稱字面量為語法糖雪标,倒是十分寫意,確實(shí)
字面量是LLVM4提供的一種簡便語法,可直接使用值來聲明一些OC對(duì)象
字符串的意外發(fā)現(xiàn)
偶然的一次失誤溉跃,發(fā)現(xiàn)以下代碼可以編譯運(yùn)行:
NSString *strThree = @"one,two,"@"three";
NSLog(@"%@", @"one,two,""three");
NSLog(@"%@", @"one,two,"@"three");
NSLog(@"%@", strThree);
結(jié)果輸出了:
one,two,three
實(shí)際上以上代碼實(shí)現(xiàn)了字符串的拼接村刨,在特定場合對(duì)代碼可讀性有特殊作用,比如SQL語句:
[db executeUpdate:
@"CREATE TABLE Person ("
@" id INTEGER PRIMARY KEY,"
@" name TEXT NOT NULL DEFAULT '',"
@" colorName TEXT NOT NULL,"
@" taps INTEGER NOT NULL DEFAULT 0,"
@" createdTime INTEGER NOT NULL,"
@" modifiedTime INTEGER NOT NULL"
@");"
]
這樣使代碼清晰可讀撰茎!
創(chuàng)建NSNumber
NSNumber *myNumber = @3;
NSNumber *yesValue = @YES;
注意: 不能把 @3 寫成 @"3" 嵌牺,會(huì)將數(shù)字轉(zhuǎn)換為NSString,造成不可預(yù)估的類型錯(cuò)誤。
默認(rèn)情況下髓梅,數(shù)字值被當(dāng)做有符號(hào)整型拟蜻,小數(shù)值被當(dāng)做double類型。通過加后綴的方式枯饿,轉(zhuǎn)換為float型:
NSNumber *valueOfPi = @3.14F; //使用float字面量聲明一個(gè)NSNumber對(duì)象
NSNumber *radius = @3U; //使用無符號(hào)integer字面量聲明一個(gè)NSNumber對(duì)象
類型后綴如下表所示:
后綴 | 類型 |
---|---|
F | float |
U | unsigned int |
L | long |
LL | long long |
使用表達(dá)式
NSNumber *sum = @(1+2);
創(chuàng)建NSArray
NSString *str1 = @"Hello";
NSString *str2 = @"World";
NSString *str3 = @"!";
NSArray *myArray1 = [NSArray arrayWithObjects:str1, str2, str3, nil];//用舊方法創(chuàng)建一個(gè)新數(shù)組
NSArray *myArray2 = @[str1, str2, str3]; //使用集合字面量創(chuàng)建一個(gè)新數(shù)組
結(jié)合字符串和NSNumber字面量聲明數(shù)組:
NSArray *strArray = @[@"Hello", @"World", @"!"];
NSArray *numArray = @[@1, @2, @3];
創(chuàng)建“二維”數(shù)組
OC中的二維數(shù)組實(shí)際上是嵌套的數(shù)組酝锅,利用的是數(shù)組能夠存儲(chǔ)對(duì)象,而數(shù)組本身也是一種對(duì)象這一事實(shí)奢方。
NSArray *numArray2d = @[@[@1, @2, @3],
@[@11, @12, @13],
@[@21, @22, @23]
];
使用二維數(shù)組搔扁,強(qiáng)烈推薦,你可以自己嘗試用 objectAtIndex 寫一下相同的訪問作對(duì)比
numArray2d[2][2]
創(chuàng)建NSDictionary
NSDictionary *dictionary2 = @{@"KEY1":@"value1",
@"KEY2":@"value2",
@"KEY3":@"value3"};
嵌套的字典聲明蟋字,字面量占盡優(yōu)勢(shì):
NSDictionary *dictionary = @{@"KEY1":@{@"KEY11":@"value11",
@"KEY12":@"value12",
@"KEY13":@"value13"},
@"KEY2":@"value2",
@"KEY3":@"value3"};
而“過時(shí)”的聲明方法來實(shí)現(xiàn)一個(gè)嵌套的字典稿蹲,實(shí)在過于繁瑣,我再也不想那樣寫了鹊奖。
下標(biāo)訪問
現(xiàn)在你已經(jīng)知道如何方便地聲明數(shù)組和字典苛聘,而字面量將賦予NSArray與傳統(tǒng)C語言數(shù)組一樣的元素訪問能力,感覺釋放了NSArray的小宇宙:
NSArray *array = @[@1, @2, @3, @4, @5];
int elementAt3 = array[3];
對(duì)比無字面量的方法:
NSArray *array = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], nil];
int elementAt3 = [array objectAtIndex:3];
節(jié)省的時(shí)間和代碼量堪稱幾何級(jí)忠聚!
而對(duì)于字典(NSDictionary)设哗,提供字符串形式的下標(biāo)訪問:
NSDictionary *dictionary = @{@"KEY1":@"value1",
@"KEY2":@"value2",
@"KEY3":@"value3"};
NSString strAtKey3 = dictionary[@"KEY3"];
重要提示:以上字面量聲明中用到值,都不能為nil两蟀,需要用[NSNull null]代替网梢;
另外,如果對(duì)象中有成員為nil赂毯,會(huì)立刻拋出異常战虏,而數(shù)組的構(gòu)造方法會(huì)聲明一個(gè)異常長度的數(shù)組對(duì)象(arrayWithObjects遇到nil后,會(huì)將nil前的對(duì)象聲明為成員党涕,nil后的對(duì)象則被丟棄7掣小),后者往往更難排查膛堤。所以字面量聲明數(shù)組啸盏,也是排坑的不二之選。如:
NSString *str1 = @"one";
NSString *str2;
NSString *str3 = @"three";
NSArray *array = @[str1, str2, str3];
假設(shè)str2==nil,會(huì)報(bào)異常:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1]'
也由拋出的異称锼睿可見回懦,字面量運(yùn)行時(shí)實(shí)際轉(zhuǎn)換成了
NSString *cArray[3] = {str1, str2, str3}; //純C數(shù)組的初始化
NSArray *array = [NSArray arrayWithObjects:cArray count:3];
創(chuàng)建可變集合對(duì)象
字面量創(chuàng)建默認(rèn)為不可變集合對(duì)象,需要可變集合對(duì)象調(diào)用mutableCopy即可:
NSMutableArray *mutableArray = [@[@1, @2, @3] mutableCopy];
字典聲明類似次企。
轉(zhuǎn)為可變集合后怯晕,也開啟了下標(biāo)操作的“新技能”——寫操作
mutableArray[3] = @"NewValue";
mutableDictionary[@"KEY3"] = @"NewValue";