Закрытие переживает свой созданный экземпляр - PullRequest
1 голос
/ 18 марта 2019

Допустим, у меня есть контроллер представления, и в его viewDidLoad я вызываю эту функцию:

func callDataSource()
{

    let dataSource = DataSource()
    dataSource.callUber {
        print("In viewDidLoad")
    }

    return
}

и этот DataSource класс

class DataSource {

    func callUber(withSuccess success: @escaping (() -> Void))
    {
        let uberManager = UberDataFetcher()
        uberManager.getPrice {
            print("In Data Source")
            success()
        }
        return
    }
}

А этот UberDataFetcher - это просто класс, который вызывает Uber API. Мой вопрос: я определил объект DataSource в рамках функции callDataSource; это означает, что объект освобождается после возврата этой функции. Как блок завершения переживает экземпляр, который его создал?

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Закрытие является объектом для целей управления памятью. Ссылка на него в обратном вызове UberDataFetcher означает, что он удерживается , что замыканием. Таким образом, он остается живым вместе со всем, что захватывает, до конца этого объема.

let uberManager = UberDataFetcher()
uberManager.getPrice {
    print("In Data Source")
    success()    // <--- Captured
}    // <--- End of scope
0 голосов
/ 18 марта 2019

@escaping помечает закрытие как возможное переживание контекста, который его создал. Закрытие - это объект, который имеет ассоциированное состояние (т. Е. Ваш список захвата) вместе со ссылкой на функцию. Ваш источник данных сохраняет закрытие, поэтому он остается в живых, по крайней мере, до тех пор, пока источник данных остается на нем. Не то чтобы это могло быть проблемой, если ваше закрытие сохраняло себя, потому что тогда самообладание продолжалось бы, по крайней мере, до тех пор, пока закрытие продолжается, то есть до тех пор, пока Источник данных удерживает его.

...