标签: rx-swift

ReactiveCocoa vs RxSwift - 优点和缺点?

所以现在有了swift,ReactiveCocoa人员已经在3.0版本中为swift重写了它

此外,还有另一个名为RxSwift的项目.

我想知道人们是否可以添加关于两个框架的设计/ api /哲学的差异的信息(请在SO的精神中,坚持真实的事情,而不是关于哪个是"最佳"的意见)

[注意StackOverflow mods:这个问题有确切的答案,答案是两个框架之间的差异.我认为这也是SO的主题

首先,我阅读ReadMe的最初印象是:

  • 作为熟悉微软"真正的"C#Rx的人,RxSwift看起来更容易识别.
  • ReactiveCococa似乎已经进入了它自己的空间,引入了新的抽象,如Signals vs SignalProducers和Lifting.一方面,这似乎澄清了一些情况(什么是热与冷信号),但另一方面,这似乎增加了框架的复杂性很多

reactive-programming swift reactive-cocoa-3 rx-swift

248
推荐指数
1
解决办法
3万
查看次数

如何使用BehaviorRelay作为RxSwift中Variable的替代?

从RxSwift4开始,Variable移动到Deprecated.swift标记Variable未来可能的弃用.建议的替代方案VariableBehaviorRelay.在发布这个问题时,由于我在网上找不到太多的教程,BehaviorRelay我在SO中发布了这样一个基本问题.

假设我正在进行webService调用,并且我收到一块JSONArray数据,在逐个解析JSON对象时我更新了我的Variable的value属性

这是我的变量声明

var myFilter = Variable<[MyFilterModel]>([MyFilterModel(data: "{:}")])
Run Code Online (Sandbox Code Playgroud)

每次我将变量更新为获取新元素时

myFilter.value.append(newModel)
Run Code Online (Sandbox Code Playgroud)

当Variable绑定到CollectionView时,collectionVie将立即使用新添加的对象更新其UI.

使用BehaviorRelay的问题

现在我的声明看起来像

var myFilter = BehaviorRelay<[MyFilterModel]>(value: [MyFilterModel(data: "{:}")])
Run Code Online (Sandbox Code Playgroud)

但最大的问题myFilter.valuereadOnly.很明显

myFilter.value.append(newModel) 
Run Code Online (Sandbox Code Playgroud)

不是解决方案.我发现我可以使用accept.

但是现在当我尝试解析响应中的每个元素并更新myFilter的值时

self?.expertsFilter.accept(newModel)
Run Code Online (Sandbox Code Playgroud)

上面的陈述给出了错误引用

无法将NewModel的值转换为预期的争论类型[NewModel]

显然,它期待一个数组而不是一个单独的元素.

解决方法:

解决方案1:

因此,一个解决方案是在临时数组中累积所有响应并且一旦完成触发 self?.expertsFilter.accept(temporary_array)

解决方案2:

如果我必须onNext在解析每个元素时向订阅者发送事件,我需要将self?.expertsFilter的值复制到new Array,将新解析的元素添加到它并返回新数组.

解决方案3:

摆脱BehaviorRelay并使用BehaviorSubject/PublishSubject

前两个声音令人沮丧,因为可能需要在解析每个元素时触发UI我不能等到解析整个响应.因此,解决方案1显然没有多大用处.

第二种解决方案更加可怕,因为它每次发送onNext事件时都会创建一个新数组(我知道它是临时的并且将被释放).

题:

因为BehaviorRelay被提议作为Variable进入两难的替代方案,我accept正确使用?有没有更好的方法来解决它?

请帮忙

rx-swift

48
推荐指数
4
解决办法
2万
查看次数

RxSwift最小的Observable.create示例

目前我正在努力让RxSwift工作.我想创建一个自定义的Observable.但我认为我做错了什么.

我已经将我做的事情提炼到这个最小的样本:

import Foundation
import RxSwift

class Example
{

    let exampleObservable : Observable<String> = Observable.create { (observer) in
        observer.on(.Next("hello"))
        observer.on(.Completed)

        return AnonymousDisposable { }
    }

    let exampleObserver : AnyObserver<String>?

    func run()
    {
        self.exampleObserver = exampleObservable.subscribeNext({ (text) -> Void in
            print(text)
        })  
    }

}

let ex = Example()
ex.run()
Run Code Online (Sandbox Code Playgroud)

它是否正确?在run方法中,subscribeNext方法由XCode自动完成.

例

但是当我运行它时,我得到以下编译错误:

Cannot Invoke 'substribeNext' with an argument list of type ((String) -> Void)
Run Code Online (Sandbox Code Playgroud)

swift rx-swift

40
推荐指数
3
解决办法
3万
查看次数

RXSwift闭包中的'[弱自我]'

我是否需要[weak self]在RXSwift subscribeNext闭包内使用?

我有代码:

    searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { searchText in
        self.viewModel.searchForLocation(searchText)
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
Run Code Online (Sandbox Code Playgroud)

我是否需要修改它以便[weak self]在闭包开始时有一个捕获列表?像这样:

    searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { [weak self] searchText in
        self?.viewModel.searchForLocation(searchText)
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
Run Code Online (Sandbox Code Playgroud)

closures swift rx-swift

31
推荐指数
2
解决办法
9777
查看次数

Swift Struct内存泄漏

我们试图尽可能地使用Swift结构.我们也在使用RxSwift,它具有关闭的方法.当我们有一个结构创建一个引用self的闭包时,它会创建一个强大的引用循环.

import Foundation
import RxSwift

struct DoesItLeak {

    var someState: String = "initial value"
    var someVariable: Variable<String> = Variable("some stuff")

    let bag = DisposeBag()

    mutating func someFoo() {

        someVariable.subscribeNext { person in

            self.someState = "something"
        }
        .addDisposableTo(bag)
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么知道这个?如果我创建100,000个DoesItLeak对象并在每个对象上调用someFoo(),我相信我有100,000个具有强引用周期的对象.换句话说,当我摆脱包含这些对象的DoesItLeak数组时,对象会留在内存中.如果我不调用someFoo(),则没有问题.

变量是一个类.所以,我可以通过使用xcode的Instruments的Allocations和Variable <String>中的过滤来看到这个内存问题

按变量过滤

在此输入图像描述

如果我尝试使用[弱自我],如下所示,我得到一个编译器错误:

someVariable.subscribeNext { [weak self] person in
Run Code Online (Sandbox Code Playgroud)

编译错误是"弱不能应用于非类型"

在实际/非示例代码中,我们通过self访问方法和变量,这是一个内存问题.

如何在保持DoesItLeak结构的同时解决此内存问题?

谢谢你的帮助.

memory-leaks swift rx-swift

29
推荐指数
3
解决办法
6409
查看次数

如何从可观察数组中创建数组的可观察对象?

我有一个Thing对象数组,我想ConvertedThing使用返回的异步函数转换为对象Observable<ConvertedThing>.

我想创建一个Observable<[ConvertedThing]>在所有转换完成后发出一个值.

如何实现这一目标?任何帮助非常感谢!

arrays swift rx-swift

29
推荐指数
2
解决办法
1万
查看次数

subscribeOn和observeOn的顺序是否重要?

我对你可以调用observables的方法subscribeOnobserveOn方法有点困惑.我读了几篇帖子,其中一个人说这没关系,只是在他的例子中使用了东西而其他人说它确实很重要.所以这是我的问题:

例如:

self.remoteService.rxGetAllLanguages()
            .observeOn(MainScheduler.instance)
            .subscribeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background))
            .subscribe({ e in
                switch e {
                case .Next(let element):

                case .Error(let e):
                    DDLogError("Error in  \(e)")
                case .Completed:
                    DDLogDebug("Completed")
                }
                }
            ).addDisposableTo(self.disposeBag)
Run Code Online (Sandbox Code Playgroud)

这是一样的:

  self.remoteService.rxGetAllLanguages()
                    .subscribeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background))
                    .observeOn(MainScheduler.instance)
                    .subscribe({ e in
                        switch e {
                        case .Next(let element):

                        case .Error(let e):
                            DDLogError("Error in  \(e)")
                        case .Completed:
                            DDLogDebug("Completed")
                        }
                        }
                    ).addDisposableTo(self.disposeBag)
Run Code Online (Sandbox Code Playgroud)

如果我正确理解它们的机制是不同的.第一个在主线程上完成所有工作,第二个在另一个线程上完成所有工作,然后调度回主线程.但我很坚定,所以有人可以帮我清楚一下吗?

multithreading swift rx-swift

25
推荐指数
1
解决办法
7574
查看次数

RxSwift - 去抖/节流"逆"

假设我有一个即时消息应用程序,每次消息到达时都会发出哔声.我想要debounce发出哔哔声,但我想播放第一条消息的嘟嘟声而不是下面的消息(在2秒的时间内).

另一个例子可能是:我的应用程序发送了输入通知(因此我正在聊天的用户可以看到我正在键入消息).我想在开始输入时发送打字通知,但只在X秒间隔发送新的通知,所以我不会为我输入的每个字符发送输入通知.

这有意义吗?那有运营商吗?可以用现有的运营商来实现吗?

这是我的第一个例子的代码.我现在正在解决它debounce,但它并不理想.如果我以1秒的间隔收到1000条消息,则在最后一条消息到达之前它不会播放声音(我想在第一条消息上播放声音).

self.messagesHandler.messages
            .asObservable()
            .skip(1)
            .debounce(2, scheduler: MainScheduler.instance)
            .subscribeNext { [weak self] message in
                    self?.playMessageArrivedSound()
            }.addDisposableTo(self.disposeBag)
Run Code Online (Sandbox Code Playgroud)

谢谢!

ios swift rx-swift

21
推荐指数
1
解决办法
7427
查看次数

BehaviorSubject vs PublishSubject

我正试图绕过黄金法则(如果有的话):

何时使用BehaviorSubject?

何时使用PublishSubject?

他们之间的区别非常明显

有很多种科目.对于这个特定的要求,PublishSubject运行良好,因为我们希望从它停止的位置继续序列.所以假设事件1,2,3在(B)中发出,在(A)连接之后我们只想看到4,5,6.如果我们使用ReplaySubject,我们会看到[1,2,3],4, 5,6; 或者如果我们使用了BehaviorSubject,我们会看到3,4,5,6等等(来源:如何考虑RxJava中的主题(第1部分))

我已经看到它Subject用于两个上下文(至少),UI上下文和监听器上下文.

  • UI上下文(以MVVM为例)

例如这里一个BehaviorSubject被使用,并且他们为什么使用它显然Subject并没有Observable,但我已经改变了BehaviorSubjectPublishSubject,但应用程序的行为仍然是相同的.

  • 监听器上下文

他们为什么要创建项目领域BehaviorSubject而不是PublishSubject

android rx-java rx-swift reactivex

21
推荐指数
3
解决办法
9561
查看次数

有没有办法不触发Variable <T>的初始值?

见下面的代码.

class ViewController4: UIViewController {
    var disposeBag = DisposeBag()
    let v = Variable(0)

    override func viewDidLoad() {
        super.viewDidLoad()

        v.asObservable()
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)

        v.value = 1
    }
}
Run Code Online (Sandbox Code Playgroud)

当它运行时,它将打印出来

0
1
Run Code Online (Sandbox Code Playgroud)

但是,我不希望它继续运行0,或者说0只是用于启动的值v.我能这样做吗?或者我必须在我使用它的时间点推迟代码?

rx-swift

18
推荐指数
1
解决办法
4175
查看次数