7

I'm trying to subscribe to an observable generated by a combineLatest, after flatMap. If I'm running this code in a struct I get this error:

Escaping closure captures mutating 'self' parameter

If I change to a class the error does not occurs. I understand that with struct I cannot asynchronously mutate the state of the struct, but, in this case I'm actually not mutating it, or am I?

There's another way to fix it without using a class?

public struct ViewModel {

    let disposeBag = DisposeBag()
    var relay1: PublishRelay<()>
    var relay2: PublishRelay<()>

    init() {
        relay1 = PublishRelay<()>()
        relay2 = PublishRelay<()>()

        Observable.combineLatest(relay1, relay2)
            .filter { tuple in 1 == 1 } // some boolean logic here
            .flatMap { _ in return Observable<Void>.just(()) } // some map filter here
            .subscribe(onNext: { _ in
                self.doCoolStuff()
            }).disposed(by: disposeBag)
    }

    func doCoolStuff() {
        // Do cool Stuff here
    }
}
chr0x
  • 1,151
  • 3
  • 15
  • 25

1 Answers1

4

All instances methods receive a reference to self as an implicit first parameter, which is why you have to capture self to call the instance method. Is you don't actually need any instance variables then make doCoolStuff() a static function and you will no longer need to call it with self. (you can use Self. as of Swift 5, or just the type name ViewModel.). You can similarly avoid this issue if doCoolStuff is a closure defined inside of init.

Josh Homann
  • 15,933
  • 3
  • 30
  • 33