2015-06-18 3 views
10

Представьте себе ситуацию, когда вы хотите асинхронно нагрузки текста с сервера и отобразить результат в ViewController'sUITextField.Swift закрытия [слабые] самостоятельно и асинхронные задачи

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 и прошел через довольно много приложений с открытым исходным кодом, которые не используют [слабое я] для асинхронных задач + закрытий.

т.е .:

Единственный раз, когда вы действительно хотите использовать [бесхозный себя] или [слабый себя], когда вы должны создать сильный опорный цикл. (Shall we always use [unowned self] inside closure in Swift)

Там нет сильного опорного цикла в моем случае.

или:

Но ясно, он все равно будет лучше использовать сильную ссылку в это обстоятельство. (Swift ARC and blocks)

Б.) Скажем, это хорошо идти с сильной ссылкой. Что происходит с ViewController, когда пользователь переходит на другую страницу в середине загрузки async? Будет ли он сохранять невидимый ViewController в памяти приложения до завершения задачи async?

ответ

11

Там нет сильного опорного цикла (цикл удержания) здесь. Если вы используете сильную ссылку на self, она будет разрешена, как только будет запущен блок отправки. Теоретически вы можете использовать здесь сильную ссылку, если вам нужно.

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

Еще лучше, я также посмотрел бы на «длительную операцию async» и решил, действительно ли он будет продолжать работать после того, как контроллер вида был уволен. Если нет, я был бы склонен также отменить запрос, а затем deinit отменить запрос. И в этом случае вы определенно захотите использовать слабую ссылку (иначе deinit не будет вызываться до завершения длительной работы async).