Подтвердить что ты не робот

Когда использовать takeUnretainedValue() или takeRetainedValue() для извлечения неуправляемых объектов в Swift?

В соответствии с Используя Swift с Cocoa и Objective-C, вы можете использовать takeUnretainedValue() и takeRetainedValue(), чтобы сообщить Swift, как управлять память объекта для такой функции:

func StringByAddingTwoStrings(CFString!, CFString!) -> Unmanaged<CFString>!

Когда мне нужно использовать takeUnretainedValue() или takeRetainedValue()?

Когда я использую ARC, тогда он всегда takeUnretainedValue()?

4b9b3361

Ответ 1

Вы используете takeRetainedValue, когда неуправляемый объект имеет счет сохранения +1, и вы хотите, чтобы ARC позаботилась о том, чтобы освободить объект, когда вы закончите. Например, если вы вызываете функцию Core Foundation с Create или Copy в имени (см. Создать правило в Руководстве по программированию управления памятью для Core Foundation), который возвращает неуправляемый объект, за который вы несете ответственность за освобождение, вы обычно используете takeRetainedValue, чтобы он был выпущен для вас (или, если вы этого не сделаете, вам нужно вручную освободить его самостоятельно с помощью CFRelease или аналогичная функция). Вы используете takeUnretainedValue, когда собственность на объект не была передана вам, и поэтому вы не хотите, чтобы ARC освобождал объект для вас, когда он выпадает из области видимости.

Итак, когда вы вызываете takeUnretainedValue vs takeRetainedValue, это просто зависит от того, какой тип объекта возвращает вызываемая функция. Как правило, если объект был возвращен из функции Core Foundation с помощью Create или Copy в имени, используйте takeRetainedValue. В противном случае используйте takeUnretainedValue.


Что происходит, если вы вызываете неправильный метод, если вы вызываете takeUnretainedValue, когда вы передаете объект +1 (например, объект, возвращенный из функции Core Foundation с помощью Create или Copy в имени), ваше приложение будет протекать, если вы явно не указали CFRelease его. Вы не можете сразу заметить случайную утечку при запуске приложения, но это можно наблюдать, наблюдая за использованием вашей памяти приложения (например, если вы профилируете приложение с помощью инструментов). Но если вы оставите эти утечки нерешенными, ваше приложение может в конечном итоге получить предупреждения о памяти.

С другой стороны, если вы вызываете takeRetainedValue объекта, который не был сохранен для вас (возвращается функцией, которая не имела Create или Copy в своем имени), приложение, скорее всего, сбой когда объект освобожден. Иногда это не проявляется сразу (не до тех пор, пока не будет решена последняя сильная ссылка), но это, как правило, приведет к катастрофическому сбою приложения.

Такой разумный выбор takeUnretainedValue vs takeRetainedValue очень важен.

Ответ 2

Цитата из NSHipster:

https://nshipster.com/unmanaged/

Неуправляемый экземпляр оборачивает тип CoreFoundation T, сохраняя ссылку на базовый объект, пока сам неуправляемый экземпляр находится в области видимости. Есть два способа получить управляемое Swift значение из неуправляемого экземпляра:

  • takeRetainedValue() возвращает управляемую Swift ссылку на обернутый экземпляр, уменьшая при этом счетчик ссылок - используйте с возвращаемым значением функции Create Rule.

  • takeUnretainedValue() возвращает управляемую Swift ссылку на обернутый экземпляр без уменьшения счетчика ссылок - используйте с возвращаемым значением функции Get Rule.