实现多代理(消息转发+弱引用数组NSPointArray))

@interface ViewController ()
@property(strong,nonatomic)NSPointerArray * arr;
@property(strong,nonatomic)NSMutableArray * mArr;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor yellowColor];
    self.mArr = [NSMutableArray array];
    self.arr = [NSPointerArray weakObjectsPointerArray];
    UILabel * label = [[UILabel alloc]init];
    NSLog(@"之前%ld",[label retainCount]);
//    [self.mArr addObject:label];
    [self.arr addPointer:label];
    NSLog(@"之后%ld",[label retainCount]);
}

最终的的结果
2020-08-14 10:10:04.174605+0800 手势[51288:5084109] 之前1
2020-08-14 10:10:04.174730+0800 手势[51288:5084109] 之后1
可见被NSPointerArray添加的对象的引用计数并没+1

如果使用NSMutableArray添加的话最终的的结果
2020-08-14 10:10:04.174605+0800 手势[51288:5084109] 之前1
2020-08-14 10:10:04.174730+0800 手势[51288:5084109] 之后2

=======================================================
需求:创建一个单例person,要求person上的更新内容在vc1、vc2实时变化

#import 
#import "MultiDelegate.h"


@protocol personDelegate 
-(void)eating;
@end

@interface person : NSObject
+(instancetype)share;
@property(strong,nonatomic) MultiDelegate  * delegate;
@end
#import "person.h"
@interface person()
@property(strong,nonatomic)NSTimer * timer;
@end
@implementation person
+ (instancetype)share
{
    static person * p = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (p == nil) {
            p = [[person alloc]init];
            p.delegate = [[MultiDelegate alloc]init];
            p.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
                [p.delegate eating];
            }];
        }
    });
    return p;
}
@end

创建MultiDelegate

#import 

@interface MultiDelegate : NSObject

- (void)addDelegate:(id)delegate;

@end
#import "MultiDelegate.h"
@interface MultiDelegate()
@property(strong,nonatomic)NSPointerArray * delegates;
@end
@implementation MultiDelegate

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.delegates = [NSPointerArray weakObjectsPointerArray];
    }
    return self;
}
- (void)addDelegate:(id)delegate {
    [self.delegates addPointer:(__bridge void*)delegate];
}
//返回方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    NSMethodSignature * signature;
    for (id delegate in self.delegates) {//存储了各个对象的代理
        signature = [delegate methodSignatureForSelector:selector];
        if (signature)
        {
            break;
        }
    }
    return signature;
}
//找到真正的消息接受者
- (void)forwardInvocation:(NSInvocation *)invocation {
    SEL selector = [invocation selector];
    for (id delegate in self.delegates) {//遍历存储给个对象的代理,发送给每个要实现代理方法的对象
        if (delegate && [delegate respondsToSelector:selector]) {
            //触发方法调用
            [invocation invokeWithTarget:delegate];
        }
    }
}

@end

在vc1、vc2中使用

vc1

- (void)viewDidLoad {
    [super viewDidLoad];
    [[person share].delegate addDelegate:self];
}
-(void)eating
{
    NSLog(@"vc1 eating...");
}

vc2

- (void)viewDidLoad {
    [super viewDidLoad];
    [[person share].delegate addDelegate:self];
}
-(void)eating
{
    NSLog(@"vc2 eating...");
}

打印结果
2019-08-30 14:30:28.119098+0800 yyModel测试[23455:763215] vc1 eating...
2019-08-30 14:30:28.119306+0800 yyModel测试[23455:763215] vc2 eating...
2019-08-30 14:30:29.119138+0800 yyModel测试[23455:763215] vc1 eating...
2019-08-30 14:30:29.119496+0800 yyModel测试[23455:763215] vc2 eating...

你可能感兴趣的:(实现多代理(消息转发+弱引用数组NSPointArray)))