如何使用带有通知的 Reactive Cocoa

How to use Reactive Cocoa with notifications

提问人:meisel 提问时间:8/12/2013 最后编辑:Kreirimeisel 更新时间:4/18/2016 访问量:8601

问:

如何从通知名称创建信号?例如,我想从:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(userDidChange:)
                                             name:kTTCurrentUserLoggedOffNotification
                                           object:nil];

到类似的东西:

[signalForName(kTTCurrentUserLoggedOffNotification) subscribeNext:^(id x){
...
}];
iOS 反应式-可可

评论


答:

10赞 allprog 8/12/2013 #1

RACExtensions 中,您可以找到该类别。为此,有一个方法:NSNotificationCenter (RACSupport)

- (RACSignal *)rac_addObserverForName:(NSString *)notificationName
                               object:(id)object;

评论

1赞 hfossli 11/14/2013
我体验到这永远不会被删除。我们需要自己处理这个信号吗?
0赞 allprog 11/14/2013
观测值与信号相关联。如果将其释放,则删除观察者。难道你在某处保留了对信号的强烈参考吗?(这是 ObjC :) 的棘手部分)
2赞 hfossli 11/14/2013
找出:)查看新答案
46赞 hfossli 11/14/2013 #2

-[NSNotificationCenter rac_addObserverForName:object:]返回无限信号。您可以像这样订阅它

目标-c

[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil]
  takeUntil:[self rac_willDeallocSignal]]
  subscribeNext:^(id x) {
     NSLog(@"Notification received");
}];

迅速

NSNotificationCenter.defaultCenter()
  .rac_addObserverForName(UIKeyboardWillShowNotification, object: nil)
  .takeUntil(self.rac_willDeallocSignal())
  .subscribeNext { (_) in
     print("Notification received")
  }

如上所述,该信号是无限的。如果你需要这个信号/订阅绑定到你的生命周期,你可以这样添加:selftakeUntil:rac_willDeallocSignal

目标-c

[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil]
  takeUntil:[self rac_willDeallocSignal]]
  subscribeNext:^(id x) {
     NSLog(@"Notification received");
}];

迅速

NSNotificationCenter.defaultCenter()
  .rac_addObserverForName(UIKeyboardWillShowNotification, object: nil)
  .takeUntil(self.rac_willDeallocSignal())
  .subscribeNext { (_) in
     print("Notification received")
  }

评论

0赞 allprog 11/15/2013
这似乎确实有效。但是,如果必须这样做,那么该方法就存在根本缺陷。信号一直存在,直到有对它们的引用。如果信号被释放,则应将其处理掉,从而移除观察者。您可能会在代码中环顾四周,可能会有对信号的强烈引用,从而阻止它被解除分配。或者,如果不是这种情况,那么请向项目报告问题,因为在我看来这不是预期的行为。
4赞 Justin Spahr-Summers 11/15/2013
@allprog 订阅者保留其信号,直到完成、错误或处置。这就是为什么无限信号会变得非常粗糙的原因。 是一个很好的解决方案,或者类似的东西,可以在某个点确定性地终止信号。-takeUntil:
2赞 allprog 11/15/2013
@JustinSpahr-Summers 感谢您的澄清。我知道我太急于喊狼了!但你在那里纠正我。:)文档是否包含这些复杂性?例如,“这是一个无限的信号”,并给出一些描述的指针,以显示需要考虑的内容。老实说,该框架似乎有一些这样的“诱杀陷阱”,如果强调这些情况下返回信号的细节会更好。
1赞 Justin Spahr-Summers 11/15/2013
@allprog 这是一个公平的观点。已就此提出问题
-1赞 Fabio 4/12/2016 #3

Swift使用版本:ReactiveCocoa 4.1

NSNotificationCenter.defaultCenter()
      .rac_addObserverForName(UIKeyboardWillShowNotification, object: nil)
      .takeUntil(self.rac_willDeallocSignal())
      .subscribeNext { (_) in
          print("UIKeyboardWillShowNotification")
      }