Ios NSNotificationCenter与ReactiveCocoa 3和Swift的正确用法是什么?
我正在玩ReactiveCocoa3和Swift,我决定做一个简单的玩具应用程序来测试如何使用ReactiveCocoa3设计一个实现MVVM模式的应用程序 基本工作人员工作得很好,但我不确定处理通知中心发出的信号的最佳方式是什么 假设有人在应用程序的某个地方触发了通知。通知名为Ios NSNotificationCenter与ReactiveCocoa 3和Swift的正确用法是什么?,ios,swift,nsnotificationcenter,reactive-cocoa,Ios,Swift,Nsnotificationcenter,Reactive Cocoa,我正在玩ReactiveCocoa3和Swift,我决定做一个简单的玩具应用程序来测试如何使用ReactiveCocoa3设计一个实现MVVM模式的应用程序 基本工作人员工作得很好,但我不确定处理通知中心发出的信号的最佳方式是什么 假设有人在应用程序的某个地方触发了通知。通知名为TimerNotification,在用户信息字典中有一个时间对象Int,可通过键TimerCount访问。现在让我们假设我有一个控制器,它希望在每次触发TimerNotification时打印消息 在旧的ObjC/RA
TimerNotification
,在用户信息字典中有一个时间对象Int
,可通过键TimerCount
访问。现在让我们假设我有一个控制器,它希望在每次触发TimerNotification
时打印消息
在旧的ObjC/RAC 2天中,我会这样做
- (void)viewDidLoad {
NSNotificationCenter * notificationCenter = [NSNotificationCenter defaultCenter];
RACSignal * timerSignal = [[notificationCenter rac_addObserverForNotificationName:@"TimerNotification" object:nil]
takeUntil:self.rac_willDeallocSignal];
[timerSignal subscribeNext:^(NSNotification * notification){
NSValue * timerCount = notification.userInfo[@"TimerCount"];
NSLog(@"Timer count is %@", timerCount);
}];
}
这将确保当控制器被释放时,订阅将被释放
我第一次尝试在Swift/RAC 3世界中做类似的事情是
private func createTimerSignalProducer() -> SignalProducer<Int, NoError> {
let notificationCenter = NSNotificationCenter.defaultCenter()
let deallocSignalProducer = self.rac_willDeallocSignal().toSignalProducer()
|> map { _ in () }
|> catch { _ in SignalProducer.empty as SignalProducer<(), NoError> }
return notificationCenter.rac_notifications(name: "TimerNotification")
|> map { $0.userInfo!["TimerCount"] as! Int }
|> takeUntil(deallocSignalProducer)
}
这实际上是可行的,但如果您想在一个不从NSObject继承的对象中执行类似的操作,该怎么办呢。因为在一个普通的Swift对象中,你不会得到rac\u willDeallocSignal()
一种可能的解决方案是将一次性数据存储在实例变量中,然后在deinit
中进行处理,但我希望避免手动处理一次性数据
更新
我最后做的事情(因为Swift对象没有根对象)是
公共协议视图模型{
}
公共类BaseViewModel:ViewModel{
私有let denitSignalProducerSinkPair=SignalProducer.buffer()
公共var脱硝生产商:信号生产商{
返回DenitSignalProducerSinkPair.0
}
脱硝{
sendNext(DenitSignalProducerSinkPair.1,())
}
}
然后在我的视图模型中
public class DetailViewModel: BaseViewModel {
let title: String
let subtitle: String
let author: String
let createdAt: NSDate
let timerCounter = MutableProperty<Int>(0)
let inputText = MutableProperty<String>("")
let reverseInputText = MutableProperty<String>("")
var formattedCreatedAt: String {
let formatter = NSDateFormatter()
formatter.dateFormat = "dd/MM/yy"
return formatter.stringFromDate(createdAt)
}
public required init(title: String, subtitle: String, author: String, createdAt: NSDate) {
self.title = title
self.subtitle = subtitle
self.author = author
self.createdAt = createdAt
super.init()
timerCounter <~ createTimerSignalProducer()
reverseInputText <~ (inputText.producer |> map { String(reverse($0)) })
}
// MARK - Private methods
private func createTimerSignalProducer() -> SignalProducer<Int, NoError> {
return NSNotificationCenter.defaultCenter().rac_notifications(name: "TimerNotification")
|> map { $0.userInfo!["TimerCount"] as! Int }
|> takeUntil(deinitSingalProducer)
}
}
public类DetailViewModel:BaseViewModel{
标题:字符串
让字幕:字符串
让作者:字符串
让createdAt:NSDate
let timerCounter=MutableProperty(0)
让inputText=MutableProperty(“”)
让reverseInputText=MutableProperty(“”)
var formattedCreatedAt:字符串{
let formatter=NSDateFormatter()
formatter.dateFormat=“dd/MM/yy”
返回格式化程序stringFromDate(createdAt)
}
公共必需的init(标题:String,副标题:String,作者:String,createdAt:NSDate){
self.title=标题
self.subtitle=副标题
self.author=作者
self.createdAt=createdAt
super.init()
计时器信号发生器{
返回NSNotificationCenter.defaultCenter().rac\U通知(名称:“TimerNotification”)
|>映射{$0.userInfo![“TimerCount”]as!Int}
|>TAKETILL(脱硝生产商)
}
}
我也遇到了同样的问题。我写了一篇关于我提出的解决方案的文章(在RAC4中)
public protocol ViewModel {
}
public class BaseViewModel: ViewModel {
private let deinitSignalProducerSinkPair = SignalProducer<(), NoError>.buffer()
public var deinitSingalProducer: SignalProducer<(), NoError> {
return deinitSignalProducerSinkPair.0
}
deinit {
sendNext(deinitSignalProducerSinkPair.1, ())
}
}
public class DetailViewModel: BaseViewModel {
let title: String
let subtitle: String
let author: String
let createdAt: NSDate
let timerCounter = MutableProperty<Int>(0)
let inputText = MutableProperty<String>("")
let reverseInputText = MutableProperty<String>("")
var formattedCreatedAt: String {
let formatter = NSDateFormatter()
formatter.dateFormat = "dd/MM/yy"
return formatter.stringFromDate(createdAt)
}
public required init(title: String, subtitle: String, author: String, createdAt: NSDate) {
self.title = title
self.subtitle = subtitle
self.author = author
self.createdAt = createdAt
super.init()
timerCounter <~ createTimerSignalProducer()
reverseInputText <~ (inputText.producer |> map { String(reverse($0)) })
}
// MARK - Private methods
private func createTimerSignalProducer() -> SignalProducer<Int, NoError> {
return NSNotificationCenter.defaultCenter().rac_notifications(name: "TimerNotification")
|> map { $0.userInfo!["TimerCount"] as! Int }
|> takeUntil(deinitSingalProducer)
}
}