iOS开发中的多代理模式(弱引用数组)
2020-03-30 本文已影响0人
梁森的简书
代理:一对一
通知:一对多
多代理模式:一对多
核心思想
消息转发,把未实现的代理方法转发给多个代理去执行。
注意点
使用NSPointArray持有多个代理对象(弱引用,代理对象的引用计数不会增加)。
1.创建一个多代理管理类的单例MultiDelegatesManager。
2.将代理对象添加到MultiDelegatesManager单例中。
3.当需要被添加到MultiDelegatesManager单例中的代理对象执行代理方法的时候,在MultiDelegatesManager单例中进行消息转发。
主要代码:
// 测试多代理
- (void)testMultiDelegates{
[[MultiDelegatesManager shareHelper] addDelegate:self];
[[MultiDelegatesManager shareHelper] sendMessage];
}
// 代理方法
- (void)doSomethings{
NSLog(@"多代理模式下通过消息转发实现代理方法。。。");
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (signature) {
return signature;
}
[_delegates compact]; // 遍历之前记得清除野指针
for (id delegate in _delegates) {
if (!delegate) {
continue;
}
signature = [delegate methodSignatureForSelector:aSelector];
if (signature) {
break;
}
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation{
SEL sel = [anInvocation selector];
BOOL isRespond = NO;
[_delegates compact];
//遍历存储给个对象的代理,发送给每个要实现代理方法的对象
for (id delegate in _delegates) {
if (delegate && [delegate respondsToSelector:sel]) {
[anInvocation invokeWithTarget:delegate]; // 发送方法
isRespond = YES;
}else{
NSLog(@"%@没有响应代理方法...", delegate);
}
}
if (!isRespond) {
[self doesNotRecognizeSelector:sel]; // 未识别的方法抛异常,避免闪退
}
}
--
@property (nonatomic, readonly, strong) NSPointerArray *delegates;
delegates是NSPointerArray类型的,对添加到其中的对象是弱引用。
添加代理对象的方法:
- (void)addDelegate:(id<mutilDelegatesDelegate>)delegate{
if (delegate && ![_delegates.allObjects containsObject:delegate]) {
[_delegates addPointer:(__bridge void*)delegate];
}
}
demo地址:https://github.com/yangguanghei/---
疑问:用__weak修饰对象之后不就是弱引用了吗?
强引用一个弱引用的对象 依旧是强引用(block内部对弱引用对象再次强引用怎么解释?iOS开发中在block中为什么要__weak和__strong配合使用)
数组内部对用weak修饰的变量(weak变量存储在弱引用表中)又进行了一次strong强引用。
block内部有时也会再次使用strong,当block结束后strong修饰的对象也会被释放。
为什么要使用NSPointerArray?
我们使用代理的时候,都会将delegate设置成weak属性,防止循环引用,这里使用NSPointerArray也是为了防止循环引用。
关于多代理,大家也可以看看QMUI中的QMUIMultipleDelegates,代码写的是高端大气,神秘莫测😄。
OC中的弱引用容器都有哪些?
除了NSPointerArray还有NSMapTable和NSHashTable