一个用于使用NSNotifications和KVO的简化Objective-C API,具有一致的术语和有用的便利功能。
仅使用块(blocks),但与NSNotification的块API不同,允许通过匹配参数而不是存储观察对象来删除。支持在观察者或被观察对象任一方释放(deallocated)时自动删除。可以选择在整个类方法上省略“pan_”前缀。
可扩展到其他类型的观察者,包括UIControl事件动作的包装器和不同应用组之间的darwin通知的包装器。
Panopticon的功能集受到了MAKVONotificationCenter的巨大影响,并且也采用了其坚实的自动删除解决方案。应用组通知的灵感来源于MMWormhole。
用Objective-C编写,但经过测试确保可以从Swift中使用。
几乎所有外部类、属性、方法都有文档,但很可能会非常需要校对和改进。当前使用jazzy构建文档的努力由于问题#158而被阻止,令人遗憾。
欢迎拉取请求。
使用 #import <Panopticon/Panopticon.h>
或 @import Panopticon;
进行导入。
有观察方法的两种通用样式,一种是你传入观察者(通常是self),另一种是当你不需要时省略观察者以提高简洁性。在这两种情况下,最后传递的块参数都是在观察触发的时刻调用的。
你可以什么都不做,当你的观察者或被观察对象释放时,观察会自动删除。不需要在 dealloc
中添加删除代码,不需要保留从观察方法返回的 PANObservation
结果。
如果你想要显式地删除一个观察,你可以保留观察方法的结果,并在其上调用 remove
。但你也可以使用 stopObserving
类方法,这与调用 -[NSNotificationCenter removeObserver:name:object:]
相同,你需要使用与你传入 observe
相同的参数调用它,并且将找到正确的观察并删除。
PANObservation *o1 = [self pan_observeForChanges:object toKeyPath:@"name" withBlock:^(id obj, PANKeyValueObservation *obs) {
NSLog(@"observed change to object's name parameter!");
}];
PANObservation *o2 = [object pan_observeChangesToKeyPath:@"flag" withBlock:^(PANKeyValueObservation *obs) {
NSLog(@"observed change to object's flag parameter!");
}];
PANObservation *o3 = [self pan_observeForNotifications:object named:@"Banana" withBlock:^(id obj, PANNotificationObservation *obs) {
NSLog(@"observed object posting Banana notification");
}];
PANObservation *o4 = [object pan_observeNotificationsNamed:@"Seaweed" withBlock:^(PANNotificationObservation *obs) {
NSLog(@"observed object posting Seaweed notification");
}];
...
[self pan_stopObservingForChanges:object toKeyPath:@"name"];
[o4 remove];
当你提供了一个观察者对象时,该对象会被作为第一个参数传递给你的块。你可以使用这个来避免创建自己的弱self指针。你可以在块定义中将该参数的类型特别化为预期的类型,从而避免不必要的类型转换。
[self pan_observeForChanges:object toKeyPath:@"name" withBlock:^(ViewController *obj, PANKeyValueObservation *obs) {
[obj handleNameChange];
}];
块的第二参数是一个观察对象,与observe
方法的结果相同。不仅可以调用这个对象的remove
方法,而且它还具有所有观察详情的访问器,例如通知对象或变更字典。
[self pan_observeForChanges:object toKeyPath:@"name" withBlock:^(id obj, PANKeyValueObservation *obs) {
NSLog(@"%@ %@ %d %@ %@", obs.changeDict, obs.keyPath, (int)obs.kind, obs.oldValue, obs.changedValue);
}];
[self pan_observeForNotifications:object named:@"Cheesecake" withBlock:^(id obj, PANNotificationObservation *obs) {
NSLog(@"%@ %@ %@", obs.notification, obs.postedObject, obs.userInfo);
}];
存在其他方法,这些方法
NSNotification
Panopticon可以轻松扩展到其他类型的观察。例如,我已经添加了以下功能
[self pan_observeControlForPress:self.button withBlock:^(id obj, PANUIControlObservation *obs) {
}];
[self.field pan_observeEvents:UIControlEventEditingDidBegin withBlock:^(PANUIControlObservation *obs) {
}];
[PANAppGroupObservation registerAppGroup:groupId];
[self pan_observeAppGroupNotificationsNamed:@"name" withBlock:^(id obj, PANAppGroupObservation *obs) {
// called with latest post
NSLog(@"%@", obs.payload);
}];
[self pan_observeReliablyAppGroupNotificationsNamed:@"updates" withBlock:^(id obj, NSArray *observations) {
// called with all posts made between last observation
// even if app was inactive or quit in the meantime
}];
[self.data pan_postWithinAppGroupNotificationNamed:@"x"];
Panopticon可以通过CocoaPods获取。要安装它,只需将以下行添加到您的Podfile中
pod "Panopticon"
另外,您可以通过在Podfile中添加以下内容来启用简写方法,这些方法将移除类别方法名称中的pan_
前缀(受MagicRecord启发)
pod "Panopticon/Shorthand"
并且,在应用的启动过程中,例如在+load
方法或应用代理的application:didFinishLaunching...
方法中,添加此类方法调用
[PANObservation setupShorthandMethods];
阅读“PanopticonShorthand.h”中的注释,了解更多详情。
如果使用pod try
或手动克隆源代码以测试示例应用,在构建CocoaPods目标之前,必须首先转到示例目录并执行pod install
,然后按照指示打开Panopticon.xcworkspace
而不是.xcodeproj
文件。注意,示例项目还有第二个目标,该目标使用静态框架进行构建。
Pierre Houston,[email protected]
Panopticon在MIT许可证下提供。有关更多信息,请参阅LICENSE文件。