Экранирующее закрытие захватывает мутирующий параметр «я» - PullRequest
2 голосов
/ 28 января 2020

Я пытаюсь подписаться на наблюдаемую, сгенерированную combineLatest, после flatMap. Если я запускаю этот код в структуре, я получаю эту ошибку:

Escaping closure captures mutating 'self' parameter

Если я перехожу на класс, ошибка не возникает. Я понимаю, что с помощью struct я не могу асинхронно изменять состояние структуры, но в этом случае я на самом деле не изменяю ее, или я?

Есть еще один способ исправить это без использования класса?

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
    }
}

1 Ответ

1 голос
/ 28 января 2020

Все методы экземпляров получают ссылку на себя как неявный первый параметр, поэтому для вызова метода экземпляра необходимо захватить self. Если вам на самом деле не нужны переменные экземпляра, тогда сделайте doCoolStuff() static функцией, и вам больше не нужно будет вызывать ее с помощью self. (вы можете использовать Self. со Swift 5 или просто имя типа ViewModel.). Подобным образом можно избежать этой проблемы, если doCoolStuff является замыканием, определенным внутри init.

...