#osxchat blog

2005/11/11

擴充 Cocoa 功能的 NSExtensions 框架

作者: lukhnos

Objective-C 語言本身有一個很強大的特色,叫作 "categories"。詳細的作用方式在此不表(可參閱中文版的 Objective-C 初學指南),簡而言之:這是一種「不必透過繼承,便能立刻增加原有 class 功能」的方法。

好比說,在使用 NSDictionary 時,我們常常可能會需要在沒查到資料時,設定一個預設值。程式通常是這樣寫的:

id x;
x=[dict valueForKey:@"key value"];
if (!x) x=defaultValue;

但是同樣的「樣式」(pattern)要寫兩行就太麻煩了。在傳統的 C 語言裡,我們可能會寫一個自製的函式,來解決這個問題:

id NSDictFindWithDefaultValue(NSString *key, id defValue);

但是這樣使用起來就太累贅且太不直觀了。透過 Objective-C 的 categories ,我們可以直接「置入」一個名叫 valueForKey: default: 的新 method,因此以上的程式可以寫成:

x=[dict valueForKey:@"key value" default:defaultValue];

我們同樣可以如法泡製,為 NSMutableDictionary 訂作一個同樣的 method ,使得在找不到 key 的情況下,直接在 dictionary object 裡插入 default value 並將之回傳。

以上的範例,可以從 NSDictionaryExtension.hNSDictionaryExtension.m 中取得。這個 extension 是 OpenVanilla OS X Loader 的一部份。OV 在寫作過程中用了兩個這類型的 categories,另一個則是 NSStringExtension

現在我們把這些 Cocoa 的「延伸功能」整理起來,變成了 NSExtensions 這個專案。取得方法很簡單:直接從 OpenFoundry 的 svn repository 中取得最新版本(最簡單的方法是用 Finder 的 "connect to server" 功能直接連接 http://svn.openfoundry.org/nsextensions/trunk)──或是使用 svn 取得。

在取得之後,進命令列,打 xcodebuild -configuration Release DSTROOT=/ install ,就可以將程式編譯完、將 NSExtensions.framework 安裝在 /Library/Frameworks 中。然後我們就可以用以下程式來測試是否安裝完成:

#import <Cocoa/Cocoa.h>
#import <NSExtensions/NSStringExtension.h>
int main() {
NSApplicationLoad();
[NSAutoreleasePool new];
NSString *s=@"test string 1 2 3 \"hello, world\" yes";
NSArray *a=[s splitBySpaceWithQuote];
NSLog([a description]);
return 0;
}

然後以下列命令列編譯之:

gcc -o test -framework Cocoa -framework NSExtensions test.m

若是結果正確地出現該字串「分裂」後的陣列內容,就表示執行成功了。("hello, world" 會被 NSArray 的 description method 自動加上引號,但實際儲存在陣列裡的字串是沒有外圍的引號的)

(是的,上述 gcc 指令也是在命令列下編譯 Cocoa 程式最簡單的方式,雖然一般說來還是建議使用 xcodebuild)

更進一步的說明,請參閱 NSExtensions 的 README.txt。這個框架以 public domain (公領域/公共財)方式釋出,歡迎自由取用。

0 篇留言:

張貼留言

? 回前頁