Быстрое закрытие [слабая самость] и асинхронные задачи
Представьте себе ситуацию, когда вы хотите асинхронно загружать текст с сервера и отображать результат в ViewController's
UITextField
.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
//... some long running async operation
if let textResponse = responseFromServer {
dispatch_async(dispatch_get_main_queue(), { [weak self] () in
self?.textField.text = textResponse
})
}
})
A.) Нужно ли использовать [слабое я] в закрытии, используемом для асинхронных вызовов?
Я думал, что мне нужно, но я не уверен, что после того, как я прочитал Q/A здесь, в StackOverflow, и прошел довольно много приложений с открытым исходным кодом, которые не используют [слабое я] для асинхронных задач + закрытий.
то есть:.
Единственный раз, когда вы действительно хотите использовать [unowned self] или [слабый self], когда вы создадите сильный ссылочный цикл. (Должны ли мы всегда использовать [unowned self] внутри закрытия в Swift)
В моем случае нет сильного ссылочного цикла.
или
Но, чтобы быть ясным, было бы лучше использовать сильную ссылку в это обстоятельство. (Swift ARC и блоки)
B.) Скажем, хорошо идти с сильной ссылкой. Что происходит с ViewController, когда пользователь переходит на другую страницу в середине загрузки async? Будет ли поддерживать невидимый ViewController в памяти приложения до завершения задачи async?
Ответы
Ответ 1
Там нет сильного опорного цикла (цикл удержания) здесь. Если вы используете сильную ссылку на self
, она будет разрешена, как только будет запущен блок отправки. Вы теоретически могли бы использовать сильную ссылку здесь, если вам нужно.
Сказав это, я бы посоветовал использовать слабую ссылку в этом случае. Нет смысла поддерживать сильную ссылку на продолжительность трудоемкого процесса исключительно с целью обновления текстового поля для представления, которое уже было отклонено. Если вы обновляете другие объекты модели или тому подобное, возможно, вам, возможно, потребуется сохранить сильную ссылку, но в этом случае вам не нужно это делать. Как общий принцип, следует освободить память как можно скорее.
Еще лучше, я также посмотрел бы на "длительную работу async" и решил, действительно ли он будет продолжать работать после того, как контроллер просмотра будет уволен. Если нет, я был бы склонен также отменить запрос, а затем deinit
отменить запрос. И в этом случае вы определенно захотите использовать слабую ссылку (иначе deinit
не будет вызываться, пока не завершится длительная работа async).