swift – 如何用RAC3替换我的KVO代码并保留现有模型?

swift – 如何用RAC3替换我的KVO代码并保留现有模型?,第1张

概述我正在研究Reactive Cocoa来改进我们的 Swift代码.作为一个起点,我想将标签的文本绑定到属性的转换值.基本上,我想替换一些KVO代码.所以,我有以下变量: @IBOutlet weak var myLabel: UILabel!var myModel: MyModel 由于我们的模型是在Objective-C中开发的,MyModel看起来像这样: @interface MyMod 我正在研究Reactive Cocoa来改进我们的 Swift代码.作为一个起点,我想将标签的文本绑定到属性的转换值.基本上,我想替换一些KVO代码.所以,我有以下变量:

@IBOutlet weak var myLabel: UILabel!var myModel: MyModel

由于我们的模型是在Objective-C中开发的,MyModel看起来像这样:

@interface MyModel : NSManagedobject@property (nonatomic,retain) NSNumber * value;@end

因此,我想做这样的事情:

myLabel.text <~ myProperty.rac_signalForSelector("value")    |> map { (value: NSNumber) in        return "\(value.integerValue + 1)"    }

但是,这显然不起作用.我该如何处理这个问题? KVO如何通常用正常的模型属性实现?

我已经找到了关于这个主题的similar post.接受的答案建议使用viewmodels.但是,我不想用viewmodels替换现有的NSManagedobject模型,而是希望保留我的模型,因为我喜欢通过XCode管理它们并通过CoreData存储它们.或者这对viewmodels来说是否可行?我错过了什么关键吗?

解决方法 这样的事情(使用RAC 3.0.0使用Xcode 6.4构建):

/// Send changes in the property value of a source object to another property on a target object,/// optionally using a mapPing function to convert values as necessary.func bind<S,T>(propertyWithKey targetKey: String,on target: NSObject,topropertyWithKey sourceKey: String,on source:NSObject,usingValueConversion sourcetoTargetValueConversion: ((S) -> T)? ) {    var (source_signal,source_sink) = Signal<T,NSError>.pipe()    var sourceSignalProducer = RACObserve(source,sourceKey).toSignalProducer()        |> start(next: {value in            if (value != nil) {                if (sourcetoTargetValueConversion == nil) {                    sendNext(source_sink,value as! T)                } else {                    let mappedValue = sourcetoTargetValueConversion!(value as! S)                    sendNext(source_sink,mappedValue)                }            }        })    var convertedValueRACSignal = toRACSignal(        source_signal            |> map {(value: T) in value as! AnyObject}    )    convertedValueRACSignal ~> RAC(target,targetKey)}/// Send changes in the property value of a source object to another property on a target object./// No conversion of values or value types is performed between source and target.func bind(propertyWithKey targetKey: String,on source:NSObject) {    var (source_signal,source_sink) = Signal<AnyObject,sourceKey).toSignalProducer()        |> start(next: {value in            if (value != nil) {                sendNext(source_sink,value!)            }        })    var convertedValueRACSignal = toRACSignal(source_signal)    convertedValueRACSignal ~> RAC(target,targetKey)}// From Colin Eberhardt's post at http://blog.scottlogic.com/2014/07/24/mvvm-reactivecocoa-swift.HTML// a struct that replaces the RAC macrostruct RAC  {    var target : NSObject!    var keyPath : String!    var nilValue : AnyObject!    init(_ target: NSObject!,_ keyPath: String,nilValue: AnyObject? = nil) {        self.target = target        self.keyPath = keyPath        self.nilValue = nilValue    }    func assignSignal(signal : RACSignal) {        signal.setKeyPath(self.keyPath,onObject: self.target,nilValue: self.nilValue)    }}// From Colin Eberhardt's post at http://blog.scottlogic.com/2014/07/24/mvvm-reactivecocoa-swift.HTMLinfix operator ~> {}func ~> (signal: RACSignal,rac: RAC) {    rac.assignSignal(signal)}// From Colin Eberhardt's post at http://blog.scottlogic.com/2014/07/24/mvvm-reactivecocoa-swift.HTMLfunc RACObserve(target: NSObject!,keyPath: String) -> RACSignal  {    return target.rac_valuesForKeyPath(keyPath,observer: target)}

在你的例子中你称之为:

bind(propertyWithKey: "text",on: myTextFIEld,topropertyWithKey: "value",on: myProperty)            { (number: NSNumber) in                return "\(number.integerValue)" as Nsstring            }

我对ReactiveCocoa有些新意,所以上面的内容可能是一个天真的实现,但它可能会指向正确的方向.

更新
这种使用通道绑定的实现更紧凑,并利用RAC内置的KVO支持:

func bind<S,usingValueConversion sourcetoTargetValueConversion: ((S) -> T)? ) {    var kvoChannelSource = RACKVOChannel(target: source,keyPath: sourceKey,nilValue: nil)    var sourceSignalWithoutNils = kvoChannelSource.followingTerminal        .filter { (var value:AnyObject?) -> Bool in            return (value != nil)        }    var mappedSourceSignal = sourceSignalWithoutNils    if (sourcetoTargetValueConversion != nil)    {        mappedSourceSignal = sourceSignalWithoutNils.map { (var s: AnyObject!) -> AnyObject! in            var result : T = sourcetoTargetValueConversion!(s as! S)            return result as! AnyObject        }    }    var kvoChannelTarget = RACKVOChannel(target: target,keyPath: targetKey,nilValue: nil)    mappedSourceSignal.subscribe(kvoChannelTarget.followingTerminal)}
总结

以上是内存溢出为你收集整理的swift – 如何用RAC3替换我的KVO代码并保留现有模型?全部内容,希望文章能够帮你解决swift – 如何用RAC3替换我的KVO代码并保留现有模型?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1015709.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存