語法糖(Syntactic sugar),也譯為糖衣語法,是由英國計算機科學家彼得·約翰·蘭達(Peter J.Landin)發明的一個術語,指計算機語言中添加的某種語法,這種語法對語言的功能并沒有影響,但是更方便程序員使用。通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯的機會。實際上沒有對代碼功能沒有影響,但是增強我們程序的可讀性的語法。
1.枚舉綁定數據類型
enum {
ObjectiveC,
Java,
Ruby,
Python,
Erlang
};
typedef NSUInteger Language;
2.點語法。OC里面所有的點語法都是。
- 屬性的@synthesize,我們知道現在連@synthesize也可以省略了,那就是說@property本身已經連帶使用了語法糖。
4.語法簡化
4.1 NSNumber
NSNumber *value;
value = @12345;
value = @123.45f;
4.2NSArray
NSArray *array;
array = @[]; // 空數組
array = @[a];// 一個對象的數組
array = @[q,w,e,r]; // 多個對象的數組
// @[] 只能是不可變數組,可變數組NSMutableArray *mutablePlanets = [@[q,w,e,r] mutableCopy];
4.3NSDictionary
NSDictionary *dict;
dict = @{}; // 空字典
dict = @{@"a":@"s"}; // 包含一個鍵值對的字典
dict = @{@"a":@"a",@"s":@"s"}; // 多個鍵值對的字典
// @{}只能是不可變字典,可變字典NSMutableDictionary *dic = [[@{@"a":@"a"}] mutableCopy];
5.對象下標
可以通過下標方式存取數組和字典的數據,類似C語言結構
5.1 NSArray
NSArray *array = @[a,s,d];
id obj = array[i]; // 通過下標方式獲取數組對象,替換原有寫法:[array objectAtIndex:i];
array[i] = newObj; // 也可以直接為數組隊形賦值。替換原有寫法:[array replaceObjectAtIndex:i withObject:newObj];
5.2NSDictionary
NSDictionary *dict = @{@"b":b,@"a":a,@"c":c};
id obc = dict[@"b"]; // 獲取o1隊形,替換原有寫法:[dic objectForKey:@"b"];
dic[@"c"] = newObj; // 重新為鍵為@"c"的對象賦值,替換原有寫法:[dic setObject:newObj forKey:@"c"];
6.@()用法
在Objective-C中我們可以用@"foo"來創建一個NSString常量,看起來似乎平淡無奇。
但它背后其實比想象的精彩,@可以被理解成一個特殊的宏,其接受一個C字符串作為參數,也可寫作@("foo")。
之所以說@是一個特殊的宏,是因為其能根據傳入的C字符串類型不同-- C字符串常量或C字符串--在運行時構建返回不同類型的NSString,參見下面的代碼:
```Objective-C
char *obtain_c_string(void)
{
return "c_string";
}
NSLog(@"%@",@"foo".class);
NSLog(@"%@", @("bar").class);
NSLog(@"%@", @(obtain_c_string()).class);
NSLog(@"%@",@"aaa");
NSLog(@"%@",@("aaa"));
輸出結果:
__NSCFConstantString
__NSCFConstantString
__NSCFString
aaa
aaa
可見,如果傳入的是C字符串常量,運行時構建的則為NSConstantString;如果傳入的是C字符串則創建是NSString。
眾所周知,Objective-C 代碼里有很多地方需要我們把代碼中的一些文法串寫成字符串再作為傳入參數,比如KVO中的keyPath 參數往往就要傳入形如propertyA.propertyB的字符串,從實用角度出發這有兩個弊端:寫字符串的時候沒有代碼提示,很容易寫錯
即便一開始寫對了,如果后來相關類重構了,keyPath的參數便失效了,而Xcode Refactor 無法掃描字符串
當我們理解了@(),再加上自定義的宏,上述兩個問題便可迎刃而解。
/**
* # 將宏的參數字符串化,c函數 strchr 返回字符串中第一個'.'字符的位置
*/
#define Keypath(keypath) (strchr(#keypath,'.')+ 1)
// 有代碼提示,可以被重構掃描到
[objA addObserver:objB forKeyPath:@Keypath(objA.property1.property2) options:nil context:nil];