ZCRMailbox 0.1.3

ZCRMailbox 0.1.3

Tests已测试
Lang语言 Obj-CObjective C
许可证 MIT
Released最新发布2014年12月

Zach Radke维护。



  • 作者:
  • Zach Radke

KVO 订阅��式受 FBKVOControllerMAKVONotificationCenter 启发,兼容回 iOS5。

要求

您需要保证最低部署目标为 iOS 5.0+ 或 OSX 10.7+,且运行于 ARC 环境下,或者知道如何选择性地在特定文件中启用 ARC。

配置环境

以下是配置 ZCRMailbox 运行的方法

  • 拖拽安装
  • CocoaPods
  • 构建框架(仅限 iOS)

在选项的海洋中迷失?强烈建议您使用 Cocoapods!

无论您选择哪种方法,您都可以通过在需要的位置导入 ZCRMailbox 来开始使用它

#import "ZCRMailbox.h"

拖拽安装

此项目中只有一个文件: ZCRMailbox.hZCRMailbox.m。您可以通过克隆仓库并将它们从 Classes 目录拖入您的 Xcode 项目中找到它们。请确保勾选了“将项目在本目标文件夹中复制的选项(如果需要)”复选框以及需要使用的任何目标。哦,如果不巧文件名冲突,您可能需要重命名文件。

构建框架(仅限 iOS)

热爱框架?克隆仓库,然后在 Xcode 中打开 Project/ZCRMailbox.xcodeproj。将目标更改为 Framework 并构建。导航到组织者并找到“项目”选项卡中的 ZCRMailbox 项目。点击旁边微小的箭头,以在 Finder 中打开“衍生数据”文件路径。正确的文件夹应该会被突出显示,并命名为类似于 ZCRMailbox-<GOBBLEDYGOOK> 的东西。导航进入那里,然后在 Build/Products/Release-<PLATFORM> 中,最后您应该看到 ZCRMailbox.framework。好了。

庆祝一下,然后把这个框架拖到更容易找到的地方。

现在您有了一个打包好的框架,您可以把它拖进您的项目,压缩并分享给朋友,或者只是留着玩玩。

使用方法

创建邮箱

使用订阅者创建一个 ZCRMailbox

ZCRMailbox *mailbox = [[ZCRMailBox alloc] initWithSubscriber:subscriber]

因为订阅者只有弱引用,所以订阅者持有其邮箱是个好主意

self.mailbox = [[ZCRMailbox alloc] initWithSubscriber:self];

如果您需要将通知消息发送到特定队列的订阅者,您也可以这么做

self.mailbox.messageQueue = [NSOperationQueue mainQueue];

使用邮箱

一旦你有了邮箱,你就可以开始添加对象的订阅,称为通知器。

NSKeyValueObservingOptions options = NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew;
[self.mailbox subscribeTo:newsletter keyPath:@"updatedDate" options:options block:^(ZCRMessage *message) {
    // Do something
}];

你可以添加任意多个通知器和键路径的订阅,所有这些都可以从一个邮箱中进行!

如果你更喜欢选择器而不是块,可以尝试以下之一

[self.mailbox subscribeTo:newsletter keyPath:@"updatedDate" options:options selector:@selector(newsletterDidUpdateDate)];
[self.mailbox subscribeTo:newsletter keyPath:@"posts" options:options selector:@selector(newsletterDidUpdatePost:))];
...
- (void)newsletterDidUpdateDate { // Do stuff }
- (void)newsletterDidUpdatePost:(ZCRMessage *)message { // Do stuff }

最后,如果你正在迁移传统的KVO代码,并希望有一个快速的插件式解决方案,直到你能够使用选择器和块,这里有这个

static void *ABCSubscriberKVOContext = &ABCSubscriberKVOContext;
...
[self.mailbox subscribeTo:newsletter keyPath:@"updatedDate" options:options context:ABCSubscriberKVOContext];
...
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (context == ABCSubscriberKVOContext) {
        // Optionally convert this to a message
        ZCRMessage *message = [[ZCRMessage alloc] initWithNotifier:object keyPath:keyPath change:change];
        // Do something
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

不是很好看,但必要时可以替代。上下文是可选的,但传统上这是一个很好的主意,以确保你接收到的通知是你想要的。

清理

当你用完邮箱后,你可以简单地让它自行释放。这将自动取消所有订阅。

如果你需要取消订阅但仍想使用邮箱,你可以使用取消订阅方法

[self.mailbox unsubscribeFrom:newsletter keyPath:@"updatedDate"];
[self.mailbox unsubscribeFrom:newsletter];
[self.mailbox unsubscribeFromAll];

测试

ZCRMailbox使用XCTest编写单元测试,并使用Travis CI进行持续集成。要自己运行测试,首先克隆仓库。然后,你可以从Xcode内部或从命令行运行测试。

Xcode内部

打开Project/ZCRMailbox.xcodeproj并确保方案设置为"ZCRMailbox"。通过从顶部菜单选择Product/Test或使用快捷键CMD+U来运行测试。

从命令行

首先安装xctool。然后从项目目录内运行rake test

深入研究

想要了解更多关于制作香肠的细节吗?本节将讨论ZCRMailbox的一些实现细节。

架构

  • ZCRMailbox对订阅者进行弱引用,并维护一个以_ZCRSubscription对象的集合为键的强引用通知器的字典。
  • _ZCRSubscription对创建它的ZCRMailbox和其他KVO观察的详细内容进行弱引用。
  • 要添加和删除订阅,ZCRMailbox会推迟到共享所有邮箱的_ZCRPostOffice
  • _ZCRPostOffice实际上处理所有的KVO观察和观察消除,以确保线程安全。它维护一个由ZCRMailbox实例发出的_ZCRSubscription对象集合。

线程安全

  • 使用简单的NSRecursiveLock实例来维持线程安全。
  • 由于所有订阅都由单个受保护的_ZCRPostOffice处理,因此可以在不同的线程上创建ZCRMailbox实例、订阅和取消订阅,而无需担心。

性能

由于KVO订阅和取消订阅需要同步执行,因此在这里使用了简单的锁定机制,而不是使用具有多个读者和单个写者的派发队列。如果每个《ZCRMailbox》实际处理自己的KVO通知,这不会成为问题,因为单个邮箱不会接收到大量订阅或取消订阅。然而,为了防止在观察的生命周期之后出现僵尸KVO更新,所有更新都通过共享的《_ZCRPostOffice》传递,该系统必须同步处理所有订阅。如果所有《ZCRMailbox》实例中发生大量的订阅和取消订阅操作,则可能会造成瓶颈。这种做法的实际情况尚不明确,如果你遇到性能问题,建议对相关的类进行性能分析。