Программа на C для преобразования текстового файла в файл CSV

Прежде всего, обратите внимание, что вам вообще не нужно беспокоиться о сохранении циклов с помощью DispatchQueue.main.asyncAfter, так как закрытие будет выполняться в некоторой точке. Поэтому, если вы слабо захватите self, вы не будете создавать постоянный цикл сохранения (предполагая, что tickle.fresh также не делает этого).

Независимо от того, помещен ли захват [weak self] список на внешнем закрытии asyncAfter полностью зависит от того, хотите ли вы сохранить self до тех пор, пока не будет вызвано закрытие (после установленного времени). Если вам не нужно self, чтобы оставаться в живых до тех пор, пока не будет вызвано замыкание, поместите [weak self] в, если вы это сделаете, тогда не помещайте его.

Поместите ли [weak self] на внутреннем замыкании (тот, который прошел до tickle.fresh), зависит от того, был ли вы уже слабый захват self во внешнем замыкании. Если вы этого не сделали, вы можете поместить [weak self], чтобы предотвратить внутреннее закрытие. Если, однако, внешнее замыкание уже слабо захвачено self, тогда внутреннее замыкание уже имеет слабую ссылку на self, поэтому добавление [weak self] к внутреннему замыканию не будет иметь эффекта.

Итак, суммируем:


DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
   tickle.fresh { msg in
      self.paint()
   }
}

self будет сохранено как внешним, так и внутренним замыканием.


DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   tickle.fresh { msg in
      self?.paint()
   }
}

self не будет сохранено ни закрытием.


DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   tickle.fresh { [weak self] msg in
      self?.paint()
   }
}

То же, что и выше, дополнительный [weak self] для внутреннего замыкания не действует, поскольку self уже слабо захвачен внешним замыканием.


DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
   tickle.fresh { [weak self] msg in
      self?.paint()
   }
}

self будет сохранено внешним замыканием, но не внутренним замыканием.


Конечно, может быть, вы не хотите, чтобы self сохранялся внешним закрытием, но вы do хотите, чтобы он был сохранен внутренним замыканием. В таких случаях вы можете объявить локальную переменную во внешнем закрытии, чтобы иметь сильную ссылку на self, когда вы можете захватить во внутреннем закрытии:

DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   guard let strongSelf = self else { return }
   tickle.fresh { msg in
      strongSelf.paint()
   }
}

Теперь self не будет поддерживаться внешним закрытием, но как только он будет вызван, если self все еще существует, он будет поддерживаться внутренним закрытием до тех пор, пока это закрытие не будет освобождено.


В ответ на:

Является сильной ссылкой на слабую ссылку, слабую или сильную ссылку?

Слабые ссылки реализуются как дополнительные, которые являются значениями типы. Поэтому вы не можете прямо иметь сильную ссылку на один - вместо этого вам сначала нужно развернуть его, а затем обратиться к основному экземпляру. В этом случае вы просто имеете дело с сильной ссылкой (точно так же, как мой пример выше с strongSelf).

Однако, если слабая ссылка - в коробке (это происходит с захват закрытия - тип значения будет помещен в ячейку, выделенную кучей), - тогда вы действительно можете иметь сильную ссылку на это поле. Эффект этого эквивалентен слабой ссылке на исходный экземпляр, у вас просто есть невидимый бит дополнительной косвенности.

На самом деле это точно , что происходит в примере где внешнее закрытие слабо захватывает self, а внутреннее замыкание «сильно фиксирует» эту слабую ссылку. Эффект заключается в том, что ни одна из них не сохраняет self.

-1
задан inVoKer 25 March 2019 в 22:29
поделиться