Удержание Strong ref для локального объекта, использующего замыкание [Swift] - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть вопрос относительно удержания ссылки Strong на локальный объект, использующий замыкание.У меня есть следующий код, в котором объект B использует метод с закрытием локального объекта типа A. Метод в объекте A использует асинхронное действие для выполнения некоторой сетевой задачи, а затем возвращает закрытие для объекта b.Так как объект A является локальным в методе в B, и поскольку я использую [слабое я] в асинхронной задаче объекта A (чтобы предотвратить сохранение цикла), объект освобождается.

Что я должен изменить вследующий код, чтобы гарантировать, что локальный объект A будет освобожден только после закрытия?

Это часть важного кода:

class A {
    var restAPI: RestAPI?

    func fetchNews(completion: (_ json: [String:Any])->()) {
        // .....
        self.restAPI.fetch(url: url, results: { [weak self] (json) in // 
            completion(json)
        })
        // .....
    }
}

class B {
    // .... 
    // ... call to updateNews()

    func updateNews() {
        let aFetcher: A() 
        aFetcher.fetchNews(completion : { 
            // <<<< // aFetcher gets released and closue never called
            // parse...
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Вам нужна сильная ссылка на верхнем уровне класса.

Однако, чтобы не сохранять ссылку постоянно, а сохранять и освобождать ее надежно, добавьте необязательное сохраненное свойство в class B и установите его в nil в завершении завершения:

class B {

    var fetcher : A?

    // MARK: - Public
    func updateNews() {
        fetcher = A()
        fetcher!.fetchNews(completion : { [unowned self] in
            // parse...

            self.fetcher = nil
        }
    }
}
0 голосов
/ 15 декабря 2018

Вы объявляете aFetcher как разрешение в области действия func updateNews ()
Когда область действия updateNews () достигает своего конца, aFetcher будет выпущен.У вас есть [слабое я] в вашей внутренней функции извлечения.На этом этапе aFetcher будет выпущен, потому что updateNews () завершит свое выполнение, и нет никаких сильных ссылок на этот объект.

Вам просто нужно добавить переменную aFetcher в класс B, чтобы убедиться, что у вас есть строгая ссылка на aFetcher .

class B {

    // MARK: - Vars
    private let aFetcher = A()

    // MARK: - Public
    func updateNews() {
        aFetcher.fetchNews(completion : {
            // parse...
        }
    }
}
...