你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 說說 Objective

說說 Objective

編輯:IOS開發基礎

Intro

在 Objective-C 中我們可以用 @"foo" 來創建一個 NSString 常量,看起來似乎平淡無奇。

但它背後其實比想象的精彩,@ 可以被理解成一個特殊的宏,其接受一個 C 字符串作為參數,也可寫作 @("foo")。

之所以說 @ 是一個特殊的宏,是因為其能根據傳入的 C 字符串類型不同——C 字符串常量或 C 字符串——在運行時構建返回不同類型的 NSString,參見下面的代碼:

char* obtain_c_string(void)
{
  return "c_string";
}
NSLog(@"%@", @"foo".class);
NSLog(@"%@", @("bar").class);
NSLog(@"%@", @(obtain_c_string()).class);

輸出結果如下:

2013-06-05 01:14:15.097 Sandbox[45804:c07] __NSCFConstantString
2013-06-05 01:14:15.098 Sandbox[45804:c07] __NSCFConstantString
2013-06-05 01:14:15.098 Sandbox[45804:c07] __NSCFString

可見,如果傳入的是 C 字符串常量,運行時構建的則為 NSConstantString;如果傳入的是 C 字符串則創建的是 NSString。

Then?

你可能會問這麼理解了又怎樣?

眾所周知,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];

這個簡單實現只算是拋磚引玉,除了 @() 配合自定義宏來字符串化代碼中的文法串,更多的用法就有待在開發中不斷發掘了。

PS: 在即將完成這篇文章的時候我發現已有國外開發者利用 @() 特性配合自定義宏,全面系統的解決了上述問題,詳情參見 libextobjc/EXTKeyPathCoding.h。

Extra

此外,@() 還可以接受 int 字面量或 int 變量作為參數,有興趣的讀者可以自行感受下。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved