测试已测试 | ✗ |
语言语言 | Objective C++Objective C++ |
许可证 | MIT |
发布最新发布 | 2014 年 12 月 |
由 Yan Rabovik 维护。
© 2013 Yan Rabovik (@rabovik 在推特上)
FastElegantDelegation 解决 3 个问题
respondsToSelector:
检查;代理通常像这样实现
@protocol SomeDelegateProtocol <NSObject>
@optional
-(void)someOptionalDelegateMethod;
// ...
@end
@interface MyClass : NSObject
@property (nonatomic,weak) id<SomeDelegateProtocol> delegate;
@end
@implementation MyClass
-(void)someMethod{
if ([self.delegate respondsToSelector:@selector(someOptionalDelegateMethod)]) {
[self.delegate someOptionalDelegateMethod];
}
}
// ...
@end
使用 FastElegantDelegation,您可以免除烦人的 respondsToSelector:
检查
@implementation MyClass
fed_use_proxy_for_delegate // just add this macro
-(void)someMethod{
[self.delegate someOptionalDelegateMethod];
}
// ...
@end
fed_use_proxy_for_delegate
宏合成了 delegate
和 setDelegate
方法;delegate
返回一个将消息转发到真实代理的 FEDProxy
类。如果代理没有对可选协议方法做出响应,代理就像消息被发送到 nil
一样什么也不做。您可以为代理属性使用任何喜欢名称,但您应该在宏中指定获取者和设置者名称。
@interface MyClass : NSObject
@property (nonatomic,weak) id<SomeDelegateProtocol> myCoolDelegate;
@end
@implementation MyClass
fed_use_proxy_for_property(myCoolDelegate,setMyCoolDelegate)
// ...
@end
代理方法可以返回任何值。
@implementation MyClass
fed_use_proxy_for_delegate
-(void)someMethod{
BOOL returnValue = [self.delegate methodReturningBOOL];
}
// ...
@end
如果将属性声明为 weak
,则代理不会被保留。当代理析构时,代理也会自动析构。您将永远不会遇到代理由 self.delegate
返回但真实代理已经析构的情况。
FEDProxy
不破坏必需/可选范式。如果您尝试调用未在代理中实现的必需方法,您将获得异常。
如果您出于某种原因需要将代理声明为强类型,这没问题。FEDProxy
将会被强存储在 ivar 中,并保留真实代理。
@interface MyClass : NSObject
@property (nonatomic, strong) id<SomeDelegateProtocol> myStrongDelegate;
@end
FEDProxy
使用快速消息转发(通过 forwardingTargetForSelector:
)和缓存来防止多次内部 respondsToSelector:
检查。
使用 `fed_synthesize_multi_delegates
` 宏,你可以在自己的类中实现多委托模式,这样你的类的客户端可以轻松地添加和移除委托。
示例
@class MyClass;
@protocol MyClassDelegate <NSObject>
-(void)myClassDidStartSomeJob;
@end
@interface MyClass : NSObject
-(void)addDelegate:(id<MyClassDelegate>)delegate;
-(void)removeDelegate:(id<MyClassDelegate>)delegate;
@end
@implementation MyClass
fed_synthesize_multi_delegates(MyClassDelegate)
-(void)someJob{
[self.delegates myClassDidStartSomeJob]; // will be sent to each delegate
}
@end
fed_synthesize_multi_delegates
生成 `addDelegate:
`、`removeDelegate:
` 和 `delegates
` 方法。
你可以根据自己的喜好命名方法。例如,你可以使用 `listener
` 名称而不是 `delegate
`。
@class MyClass;
@protocol MyClassListener <NSObject>
-(void)myClassDidStartSomeJob;
@end
@interface MyClass : NSObject
-(void)addListener:(id<MyClassListener>)delegate;
-(void)removeListener:(id<MyClassListener>)delegate;
@end
@implementation MyClass
fed_synthesize_multiproxy(MyClassListener, addListener, removeListener, listeners)
-(void)someJob{
[self.listeners myClassDidStartSomeJob];
}
@end
如果方法返回值,则返回值将从响应选择器的列表中的第一个委托。
FEDMultiProxy
类是 NSProxy
的子类,它允许向单个第三方资源添加多个委托。
例如,你可以将多个委托分配给一个 `UIScrollView
`。
__typeof(self) __weak weakSelf = self;
FEDMultiProxy *multiProxy = [FEDMultiProxy proxyWithDelegates:@[firstDelegate, secondDelegate]
protocol:@protocol(UIScrollViewDelegate)
retainedByDelegates:YES
onDealloc:^{
weakSelf.scrollView.delegate = nil;
}];
self.scrollView.delegate = multiProxy;
你不需要保持对 `FEDMultiProxy
` 对象的强引用。每个委托会自动保留它,当所有委托都无法访问时,它将被释放。此时将调用 `onDealloc
` 块,你可以在那里将目标委托设置为 `nil
`。
MIT 许可证。