2012-12-12 38 views
1

我有一個通用例程,它需要幾個參數。 喜歡的東西:Objective-C - 用回調參數存儲塊

-(id) doStuff:(int)A:(int)B:(int)C { 
    //doStuff 
    return object; 
} 

我有一個UITableViewController,裏面有一些定製的細胞,每一個都有自己的ID。當「保存」命中時,這些單元格將被迭代,並且一些單元格在保存時需要「額外行爲」。

到目前爲止,我創建了一個'回調'對象,它在自定義單元格中存儲NSString *和一個委託。當被「保存」,單元外觀,是否有任何回調申請和使用

SEL sel = NSSelectorFromString(Sel); 
if([Del respondsToSelector:sel]) 
    [Del performSelector:sel withObject:Cell]; 

現在工作起來有些好......,但是,它需要我傳遞給上做一個開關/箱的方法已通過的單元的ID,我想避免這種情況。

這就是爲什麼我想使用塊,但我真的不知道如何將參數化塊存儲在變量中。

我想要做的事:

聲明一個功能塊doStuff

id (^doStuff) (int, int, int) = ^(int A, int B, int C) { 
    //does Stuff 
}; 

並添加先前創建的塊回調

[Cell addCallback:(^doStuff)(1, 2, 3)]; 

塊必須在那個時刻未被調用,而是存儲在電池,僅稱它時,時間是正確的。 我該如何正確解決這個問題?

非常感謝。

編輯:我還想避免的是將塊的參數存儲在單元格中,並在調用時傳遞它們,因爲這會要求我進一步不必要地專門化單元格。

回答

1

這聽起來像你想要的是調用你的塊,像這樣一個塊:

[cell addCallback:^{ doStuff(1, 2, 3); }]; 

但是,這是一個相當奇怪的和令人費解的設計。看起來似乎有一種方法可以只用一個代碼塊來編寫代碼,但是如果沒有更好的理解你正在做的事情,很難提供一個特定的解決方案。

+0

這似乎總結了我想要做的事情。它可能會覺得奇怪,但塊也是如此。我會嘗試並給你反饋。謝謝:) – ATaylor

0

最簡單的方法是創建一個typedef,其中包含塊參數的外觀應該如何,然後使用它來聲明新屬性/ ivar。下面的示例代碼是從明智的TableView框架SCCellActions類複製:

typedef void(^SCCellAction_Block)(SCTableViewCell *cell, NSIndexPath *indexPath); 

@interface SCCellActions : NSObject 
... 
@property (nonatomic, copy) SCCellAction_Block willDisplay; 
... 
@end 

然後,您可以設置屬性如下:

cellActions.willDisplay = ^(SCTableViewCell *cell, NSIndexPath *indexPath) 
{ 
    cell.backgroundColor = [UIColor yellowColor]; 
}; 

同樣,你可以聲明如下參數:

... 
- (void)callActionBlock:(SCCellAction_Block actionBlock) 
{ 
    if(actionBlock) 
    { 
     actionBlock(self.cell, self.cellIndexPath); 
    } 
} 
... 

在這種情況下,該方法應該像這樣調用:

[myObject callActionBlock:^(SCTableViewCell *cell, NSIndexPath *indexPath {cell.backgroundColor = [UIColor yellowColor];}]; 
+0

不,我不認爲這就是我要找的。你看,這個設置將要求我進一步專門化我的單元格,或者進入開關盒以確定與ID匹配的參數。不管怎麼說,還是要謝謝你。 – ATaylor

0

這個答案是基於查克的建議,並描述了我遇到的陷阱實現它。

創建:

Cell = [self CreateCell]; 
[Cell addCallback:^{ return doStuff(Cell, 1, 2, 3, 4) } At:ON_SAVE]; 

doStuff是一個局部塊,所述細胞之前聲明。我無法將其直接添加到單元格中,因爲我還需要對該塊內的調用單元格的引用。

此時的陷阱:類變量。 一個塊只會保留......或者說'複製'...局部變量,而不是類變量。 假設'Cell'是一個類變量並由'CreateCell'設置,該塊將在該塊執行時與Cell的值一起工作。

因此,重要的是要記住聲明一個局部變量,如果有必要,它將假設類變量的值。

存儲:

- (void) addCallback:(CallBlock_t)B At:(int)at { 
    //Creates a Callback-Object and passes it the block and adds it to an Array. 
} 

- (id) initWithBlock:(CallBlock_t)B At:(int)at { 
    self = [super init]; 
    if(self) { 
     Block = [B copy]; //Yes, Copy. Not retain. 
     When = at; 
    } 
    return self; 
} 

陷阱在這一點:如果塊僅僅保留,從調用函數中的局部塊將走出去的範圍,並計劃將失敗,「錯誤訪問」。複製解決了這個問題。

當然,你需要釋放塊(一旦你使用它(在回調類的dealloc中),但這是一個給定的。

我希望這個小解釋能夠拯救某個人一些悲傷。