WPObserver 0.1.6

WPObserver 0.1.6

wuyanghu维护。



WPObserver

CI Status Version License Platform

描述:git仓库

iOS的代理和block属于一对一模式。有时需要实现一对多的需求,通知可以实现,但有时业务关联很紧密,通知的可读性不好。

项目中目前使用的是GCDMulticastDelegate,发现其有一些缺点

  1. GCDMulticastDelegate中的消息调用都在消息转发中进行,消息转发在iOS中代价较高。
  2. 其消息调用都是异步提交到队列,导致堆栈信息无法跟踪。
  3. 库也比较老了,偶现闪退,体验不好。
  4. 使用起来不太方便,需要先定义multiDelegate,添加代理,不需要移除,使用时还需要判断方法是否存在。
@property(nonatomic, strong) GCDMulticastDelegate <BLEnterpriseManagerDelegate> *multiDelegate;

- (instancetype)init {
    if (self = [super init]) {
        self.multiDelegate = (GCDMulticastDelegate <BLEnterpriseManagerDelegate> *) [[GCDMulticastDelegate alloc] init];
    }
    return self;
}

- (void)addDelegate:(id <BLEnterpriseManagerDelegate>)delegate delegateQueue:(dispatch_queue_t)queue {
    [_multiDelegate addDelegate:delegate delegateQueue:queue];
}

- (void)removeDelegate:(id <BLEnterpriseManagerDelegate>)delegate {
    [_multiDelegate removeDelegate:delegate];
}

if ([self.multiDelegate hasDelegateThatRespondsToSelector:@selector(enterpriseManager:didClearAllOrgs:)]) {
                        [self.multiDelegate enterpriseManager:self didClearAllOrgs:YES];
                    }

思考

一对多就是观察者模式的使用,完全可以自己实现。

  1. 观察者使用封装在NSObject扩展中,任何对象都可以添加观察者对象。不再需要在被观察者中声明什么。
  2. 消息调用使用了NSInvocation,不走消息转发。
  3. 如果不设置队列,默认都回到主线程;也可指定队列。
  4. 方法不存在,不需要外部判断。内部打印错误日志,注意观察。

使用

  1. 导入头文件 #import "NSObject+BLObserver.h"
  2. 添加观察者
[_customView wp_addObserver:self];
    
    _observer1 = [WPViewObserver new];
    _observer1.title = @"observer1 ";
    [_customView wp_addObserver:_observer1];
    
    _observer2 = [WPViewObserver new];
    _observer2.title = @"observer2 ";
    [_customView wp_addObserver:_observer2 delegateQueue:dispatch_queue_create("observer2", DISPATCH_QUEUE_SERIAL)];//指定队列
  1. 被观察者通知观察者:带参数调用
    [self wp_notifyObserverWithAction:@selector(update), nil];
    [self wp_notifyObserverWithAction:@selector(update:), 1,nil];
    [self wp_notifyObserverWithAction:@selector(update:count2:), 1,2,nil];
  1. 观察者监听
- (void)update:(NSInteger)count{
    NSLog(@"detail update %ld",count);
}

- (void)update:(NSInteger)count count2:(NSInteger)count2{
    NSLog(@"detail update %ld,%ld",count,count2);
}
  1. 退出页面后内存自动释放
2021-02-06 23:18:16.655618+0800 WPObserver_Example[58471:640255] WPDetailViewController dealloc
2021-02-06 23:18:16.656013+0800 WPObserver_Example[58471:640255] WPViewObserver dealloc observer2
2021-02-06 23:18:16.656214+0800 WPObserver_Example[58471:640255] WPViewObserver dealloc observer1
2021-02-06 23:18:16.656621+0800 WPObserver_Example[58471:640255] WPView dealloc

总结

  1. 大部分监听和移除操作都在主线程,如果感觉线程不安全,也可以加个信号量。
  2. 观察者模式使用简单,要考虑到通用性和多参数问题。
  3. 多参数要考虑到int,double等基本类型。
  4. weak不持有观察者,不需要释放。只管监听和通知观察者。如果有特殊情况,不需要监听了,可以调用[wp_removeObserver],移除监听;对于单例的观察者,需要手动移除。

安装

WPObserver可以通过CocoaPods获取。要安装它,只需将以下行添加到您的Podfile中

pod 'WPObserver'

作者

[email protected][email protected]

许可

WPObserver遵循MIT许可协议。有关更多信息,请参阅LICENSE文件。