使用 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 中的代码过多),你还应该将它们抽离成独立的方法,这种情况的话可能用代理会更好一些。
摘自:自定义控件