使用 Block
另一個選擇是使用 block。再一次用餅狀圖舉例,代碼看起來大概是這樣:
@interface PieChart : UIControl
@property (nonatomic,copy) void(^selectionHandler)(PieChartSection* selectedSection);
@end
在選取行為的代碼中,你只需要執行它。在此之前檢查一下block是否被賦值非常重要,因為執行一個未被賦值的 block 會使程序崩潰。
if (self.selectionHandler != NULL) {
self.selectionHandler(self.selectedSection);
}
這種方法的好處是可以把相關的代碼整合在視圖控制器中:
- (void)setupPieChart
{
self.pieChart.selectionHandler = ^(PieChartSection* section) {
// 處理區塊
}
}
就像代理,每個動作通常只有一個 block。另一個重要的限制是不要形成引用循環。如果你的視圖控制器持有餅狀圖的強引用,餅狀圖持有 block,block 又持有視圖控制器,就形成了一個引用循環。只要在 block 中引用 self 就會造成這個錯誤。所以通常代碼會寫成這個樣子:
__weak id weakSelf = self;
self.pieChart.selectionHandler = ^(PieChartSection* section) {
MyViewController* strongSelf = weakSelf;
[strongSelf handleSectionChange:section];
}
一旦 block 中的代碼要失去控制 (比如 block 中要處理的事情太多,導致 block 中的代碼過多),你還應該將它們抽離成獨立的方法,這種情況的話可能用代理會更好一些。
摘自:自定義控件