2012-06-24 86 views
4

我正在嘗試爲一個Objective-c類創建一個很好的基於塊的初始化程序。我在一個超類中聲明它,我希望它在所有的子類中都有用。在運行時動態修改塊

現在我有:

+ (id)createWithBlock:(void (^) (id newObject))creationBlock { 
    id newObject = [self object];  
    creationBlock(newObject); 
    return newObject; 
} 

哪個都可以使用(在子類中)這樣:

Record *newRecord = [Record createWithBlock:^(id newObject) { 
    Record *newRecord = (Record *)newObject; 
    newRecord.name = @"Ginger"; 
    newRecord.type = @"Rhizome"; 
}]; 

這是正常的現在,但我很想得到這個回吐向下一點。理想情況下,它看起來像:

Record *newRecord = [Record createWithBlock:^{ 
    name = @"Ginger"; 
    type = @"Rhizome"; 
}]; 

但這似乎有點雄心勃勃。我也不會介意的只是:

Record *newRecord = [Record createWithBlock:^(Record *newRecord) { 
    newRecord.name = @"Ginger"; 
    newRecord.type = @"Rhizome"; 
}]; 

這最後一個版本是困難的,因爲它似乎鐺做一些編譯時類型檢查塊。上面不會編譯createWithBlock的定義:我有上面的,因爲:incompatible block pointer types initializing 'void (^)(struct Record *)', expected 'void (^)(struct objc_object *)

如果它沒有做這種強類型檢查,我可以在運行時調整方法。 (或者,也許我現在可以這樣做,如果我鍵入我的塊聲明?)

我一直在這裏撓我的頭一陣子,我已經讀了幾乎所有我能找到的塊的文檔,包括鐺規格。如果有人有我很想聽到的想法,這是一個開源項目,我認爲這種模式會讓所有Objective-C用戶受益。

現在我的想法傾向於imp_implementationWithBlock()。但是之後我需要根據其中的內容「構建」一個新的IMP,並將其交換出去。可行?

+0

究竟是什麼實現了剛剛初始化屬性後*構造函數? (不管怎麼說,我只是婉轉了冗長的語法;直到Apple認爲適合向ObjC中添加泛型,這是一個不會讓使用API​​的人感到意外的成語。) – millimoose

+0

它更像是一種風格/可讀性而非功能性的東西。通過初始化塊中的所有內容,可以看到屏幕上某個位置的對象。而對於更復雜的初始化,這對我來說似乎很有用。 (許多其他語言都有這種類型的創作)。編輯:其他幾種語言。 –

+0

可能不是在超類中定義單個初始化程序,而是可以讓預處理程序宏爲您生成第三個語法變體的類型安全定義。有點boilerpottish,但似乎是一個合理的nonmagical妥協。 – millimoose

回答

3

你使用什麼編譯器?我相信LLVM的最新版本將接受您提供的最後一個代碼示例。 (即你所給的錯誤不應該發生)。

特別是,這對於LLVM 3.1適用於Xcode 4.3.3中全新的Xcode項目。

+0

這非常有幫助!愚蠢的是,我的'createWithBlock'正在使用LLVM 3.1進行編譯,並且我使用的方法是使用LLVM GCC 4.2編譯的。切換到新的編譯器,它確實有效!我的「理想」的任何想法? –

+0

如果你真的想減少字符數,我能想到的只是使用宏或者使用類似傳遞var_args鍵值對列表來設置。 –

+0

那麼,我已經有了一個需要NSDictionary的創建方法。我希望能有某種方式來「檢查」一個塊並基於它創建一個新的塊? –