-
Notifications
You must be signed in to change notification settings - Fork 1
MDListener
MDListener是一个高扩展性的、易用的监听者模式的实现
TMDListener: 测试用例(监听者)
TListenerLoginModule: 登录模块(被监听者)
@protocol TMDListenerLoginNotification <NSObject>
- (void)didLogin;
@end
登录模块定义协议,监听者遵守协议。这样登录模块就可以通过MDListener来触发监听者的协议方法了。
@property (nonatomic, strong) MDListener <id <TMDListenerLoginNotification>> *listeners;
其中,listeners的类型为一个泛型,它只接受其指定类型的实例作为监听者。在Demo中,也就是实现了TMDListenerLoginNotification协议的实例对象。这在后续步骤中也会提及。
在Demo中即为+ (void)login方法
+ (void)login {
//do login
[[self sharedInstance].listeners performAction:^(id<TMDListenerLoginNotification> _Nonnull listener) {
[listener didLogin];
}];
}
@interface TMDListener : XCTestCase <TMDListenerLoginNotification>
- (void)setUp {
[[TListenerNetworkingModule sharedInstance].listeners addListener:self];
[super setUp];
}
这里注意,由于登录模块在声明listeners属性的时候,通过泛型定义了其只接受遵循TMDListenerLoginNotification协议的id类型,因此如果步骤4中没有声明自己实现该协议,这里的addListener的时候就会报warning。这里利用了编译器来减少bug的产生。
- (void)didLogin {
NSLog(@"didLogin");
self.hasLogin = YES;
}
- (void)testListener {
[TListenerLoginModule login];
XCTAssertTrue(self.hasLogin);
}
MDListener帮助被监听者管理所有的监听者,而其声明的监听者类型是一个泛型。因此,当被监听者声明MDListener对象的时候,可以定义监听者类型。也就是说,被监听者决定了监听者类型,这通常是id类型带一个协议,而通常该协议由被监听者在头文件中声明,换句话说,被监听者通过这种方式,决定监听者必须实现哪些方法(或者可选实现)。
当然,被监听者也可以定义该泛型为其他类型,比如在特定的情况下,被监听者可以定义监听者的类型为UIViewController等其他类型,或者开发者在项目中自定义的其他类型,由此来完成特定的任务。
MDListener帮助被监听者管理所有的监听者,并自动在监听者被析构的时候移除。因此,监听者无需在dealloc方法中调用类似于removeListener的方法。
和NSNotificationCenter模式相比,MDListener可以通过泛型加协议的方式,规定监听必须实现一些方法。开发者在写监听者代码的时候,如果忘记实现这些方法,则编译器会报warning。另外,参数传递通过函数形参的方式传递,而不是NSDictionary。开发者在写监听者代码时,不会因为不了解NSDictionary的数据结构,以及这些数据所对应的业务含义,而产生困惑,从而产生不必要的开发成本。
和KVO相比,MDListener不需要依赖属性即可完成监听者模式。当然,KVO也有其优势,在KVO模式下,被监听者无需为实现监听者模式,提供任何额外的代码。