Swift   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了swift – 如何用RAC3替换我的KVO代码并保留现有模型?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

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

@IBOutlet weak var myLabel: UILabel!
var mymodel: Mymodel

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

@interface Mymodel : NsmanagedObject
@property (nonatomic,retain) NSnumber * value;
@end

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

@H_708_21@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 source@R_965_10586@rgetValueConversion: ((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 (source@R_965_10586@rgetValueConversion == nil) {
                    sendNext(source_sink,value as! T)
                } else {
                    let mappedValue = source@R_965_10586@rgetValueConversion!(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 macro
struct 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.html
infix 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.html
func 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 source@R_965_10586@rgetValueConversion: ((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 (source@R_965_10586@rgetValueConversion != nil)
    {
        mappedsourceSignal = sourceSignalWithoutNils.map { (var s: AnyObject!) -> AnyObject! in
            var result : T = source@R_965_10586@rgetValueConversion!(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代码并保留现有模型?所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。