Удалить из массива AnyCancellable, когда издатель заканчивает - PullRequest
0 голосов
/ 14 марта 2020

Есть ли хороший способ обработать массив AnyCancellable, чтобы удалить сохраненный AnyCancellable после его завершения / отмены?

Скажите, у меня есть

import Combine
import Foundation

class Foo {

    private var cancellables = [AnyCancellable]()

    func startSomeTask() -> Future<Void, Never> {
        Future<Void, Never> { promise in
            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
                promise(.success(()))
            }
        }
    }

    func taskCaller() {
        startSomeTask()
            .sink { print("Do your stuff") }
            .store(in: &cancellables)
    }

}

Каждый раз taskCaller вызывается, AnyCancellable создается и сохраняется в массиве. Я хотел бы удалить этот экземпляр из массива после его завершения, чтобы избежать потери памяти.

Я знаю, что могу сделать что-то подобное вместо массива

var taskCancellable: AnyCancellable?

И сохранить отменяемый, выполнив:

taskCancellable = startSomeTask().sink { print("Do your stuff") }

Но это закончится, чтобы создать несколько отдельных отменяемых и может загрязнить код. Я не хочу такой класс, как

class Bar {

    private var task1: AnyCancellable?
    private var task2: AnyCancellable?
    private var task3: AnyCancellable?
    private var task4: AnyCancellable?
    private var task5: AnyCancellable?
    private var task6: AnyCancellable?

}

1 Ответ

1 голос
/ 14 марта 2020

Это хорошая идея, но удалить нечего. Когда завершение (окончание sh или отмена) происходит по конвейеру, все в конвейере отписывается в хорошем порядке, все классы (объекты подписки) освобождаются, и так далее. Таким образом, единственное, что по-прежнему значимо «живо» после того, как ваше Future выпустило значение или ошибку, - это Sink в конце конвейера, и он крошечный.

Чтобы увидеть это, запустите этот код

for _ in 1...100 {
    self.taskCaller()
}

и используйте инструменты для отслеживания ваших ассигнований. Конечно же, после этого есть 100 объектов AnyCancellable, на общую сумму 3 КБ. Нет фьючерсов; ни один из других объектов, неправильно размещенных в startSomeTask, до сих пор не существует, и они настолько крошечные (48 байт), что не имеет значения, если они это сделали.

...