这个 NSProxy
子类允许您轻松地进行代理方法链接。创建一个 PHFDelegateChain
的实例,告诉它应该转发给哪个对象,并将其作为对象的代理。每当调用链上的方法时,它都会将其转发到已注册的对象。
[tableView setDelegate:(id<UITableViewDelegate>)[PHFDelegateChain delegateChainWithObjects:anObject, anotherObject, nil]];
为了尽可能的透明,PHFDelegateChain
具有以下自省行为
respondsToSelector:
如果至少有一个已注册的对象响应该选择器,则返回 YES
。conformsToProtocol:
如果至少有一个已注册的对象遵守该协议,则返回 YES
。此外,仅将 void
方法传递给链上的多个对象。非 void
方法返回一个值,因此只有链上第一个响应该选择器的对象会收到它,从而在第一个能够处理调用的对象处断开链。这种断开行为也可以应用于 void
方法,通过设置 __breaking
属性为 YES
。
存储链对象的 NSMutableArray
只是对它们进行弱引用,以避免循环引用。
通常,一个实现代理的类会定义一个伴随的协议并强制实施于代理对象。在这些情况下,有必要将 PHFDelegateChain
实例进行类型转换。请注意,在链对象内部实现所需的协议方法是您的责任。否则,当链接收到它无法转发的调用时,应用程序将会崩溃。
@interface EditingDelegate : NSObject <UITableViewDelegate> @end
@interface SelectionDelegate : NSObject <UITableViewDelegate> @end
//
PHFDelegateChain *chain = [PHFDelegateChain delegateChainWithObjects:[EditingDelegate new], [SelectionDelegate new], nil];
[tableView setDelegate:(id<UITableViewDelegate>)chain]; // Protocol typecast needed
委托链在许多情况下都很有用,例如:
- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
if ([_delegate respondsToSelector:@selector(tableView:willBeginEditingRowAtIndexPath:)])
[_delegate tableView:tableView willBeginEditingRowAtIndexPath:indexPath];
}
首选方法是使用 CocoaPods。只需将 PHFDelegateChain
列为一个依赖项。
dependency 'PHFDelegateChain', '~> 1.0'
如果您不能使用或不想使用CocoaPods(您确实应该使用,它很棒!),只需获取 PHFDelegateChain.{h,m}
文件并将其放入您的项目中即可。
要在本项目中进行破解,您需要已安装 CocoaPods。如果您还没有,请获取它
$ gem install cocoapods
获取所有依赖项并初始化工作区
$ pod install PHFDelegateChain.xcodeproj
打开工作区
$ open PHFDelegateChain.xcworkspace
请确保为新功能和更改添加测试。
PHFDelegateChain
使用 MIT 许可证发布。