iOS技术知识点

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

上一篇下一篇

猜你喜欢

热点阅读