Автоматический подсчет ссылок
Автоматический подсчет ссылок ( ARC ) — это управления памятью функция Clang компилятора , обеспечивающая автоматический подсчет ссылок для Objective-C и Swift языков программирования . Во время компиляции он вставляет в объектный код сообщения retain
и release
[1] [2] которые увеличивают и уменьшают количество ссылок во время выполнения, помечая для освобождения эти объекты , когда количество ссылок на них достигает нуля.
ARC отличается от отслеживания сборки мусора тем, что здесь нет фонового процесса, который асинхронно освобождает объекты во время выполнения. [3] В отличие от отслеживания сборки мусора, ARC не обрабатывает циклы ссылок автоматически. Это означает, что пока на объект существуют «сильные» ссылки, он не будет освобожден. Соответственно, сильные перекрестные ссылки могут создавать взаимоблокировки и утечки памяти . Разработчик должен разорвать циклы, используя слабые ссылки . [4]
Apple Inc. использует ARC в своих операционных системах, таких как macOS ( OS X ) и iOS . Ограниченная поддержка (ARCLite) [5] доступен начиная с Mac OS X Snow Leopard и iOS 4 , с полной поддержкой в Mac OS X Lion и iOS 5 . [6] Сборка мусора была объявлена устаревшей в OS X Mountain Lion в пользу ARC и удалена из библиотеки времени выполнения Objective-C в macOS Sierra . [7] [8]
Цель-C
[ редактировать ]При включении ARC компилятор применяет следующие правила:
retain
,release
,retainCount
,autorelease
илиdealloc
не может быть отправлено на объекты. Вместо этого компилятор автоматически вставляет эти сообщения во время компиляции, включая[super dealloc]
когдаdealloc
переопределяется. [9]// Without ARC - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } // With ARC - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; // [super dealloc] is called automatically }
- Программы не могут выполнять прямую трансляцию между
id
иvoid *
. [9] Это включает в себя приведение между объектами Foundation и объектами Core Foundation. Программы должны использовать специальные приведения или вызовы специальных функций, чтобы сообщить компилятору дополнительную информацию о времени жизни объекта.// Without ARC - (NSString *)giveMeAString { CFStringRef myString = [self someMethodThatCreatesACFString]; NSString *newString = (NSString *)myString; return [newString autorelease]; } // With ARC - (NSString *)giveMeAString { CFStringRef myString = [self someMethodThatCreatesACFString]; // retain count is 1 NSString *newString = (__bridge_transfer NSString *)myString; // the ownership has now been transferred into ARC return newString; }
- Пул автоматического освобождения можно использовать для временного выделения объектов и сохранения их в памяти до тех пор, пока пул не будет «опустошен». Без ARC,
NSAutoreleasePool
Для этой цели может быть создан объект. ARC использует@autoreleasepool
вместо этого блоки, которые инкапсулируют выделение временных объектов и освобождают их при достижении конца блока. [9]// Without ARC - (void)loopThroughArray:(NSArray *)array { for (id object in array) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Create a lot of temporary objects [pool drain]; } } // With ARC - (void)loopThroughArray:(NSArray *)array { for (id object in array) { @autoreleasepool { // Create a lot of temporary objects } } }
- Программы не могут вызывать функции
NSAllocateObject
иNSDeallocateObject
[9] - Программы не могут использовать указатели объектов в структурах C (
struct
с) [9] - Программы не могут использовать зоны памяти (
NSZone
) [9] - Чтобы правильно взаимодействовать с кодом, отличным от ARC, программы не должны использовать методы или объявленные свойства (если явно не выбран другой метод получения), начинающиеся с
new
. [9]
Декларации о собственности
[ редактировать ]ARC вводит некоторые новые атрибуты объявления свойств, некоторые из которых заменяют старые атрибуты.
Без АРК | С АРК | С ARCLite [Примечание 1] |
---|---|---|
retain |
strong
| |
assign (для типов объектов) |
weak |
unsafe_unretained
|
copy
|
- ^ ARCLite — это ARC, но без обнуления слабых ссылок (используется при развертывании в менее функциональной операционной среде, чем требует ARC).
Обнуление слабых ссылок
[ редактировать ]Обнуление слабых ссылок — это функция Objective-C ARC, которая автоматически очищает (устанавливает значение nil
) локальные переменные со слабыми ссылками, переменные экземпляра и объявленные свойства непосредственно перед тем, как объект, на который указывает, начинает освобождаться. Это гарантирует, что указатель переходит либо к допустимому объекту, либо к nil
и позволяет избежать висячих указателей . До появления этой функции «слабые ссылки» относились к ссылкам, которые не сохранялись, но не были установлены на nil
когда объект, на который они указывали, был освобожден (эквивалентно unsafe_unretained
в ARC), что может привести к зависанию указателя. Программисту обычно приходилось следить за тем, чтобы все возможные слабые ссылки на объект были вручную установлены в ноль при его освобождении. Обнуление слабых ссылок устраняет необходимость в этом.
Обнуление слабых ссылок указывается с помощью объявленного атрибута свойства. weak
или с помощью атрибута переменной __weak
.
Обнуление слабых ссылок доступно только в Mac OS X Lion (10.7) или более поздней версии и iOS 5 или более поздней версии, поскольку они требуют дополнительной поддержки со стороны среды выполнения Objective-C. Однако некоторые классы OS X в настоящее время не поддерживают слабые ссылки. [9] Код, который использует ARC, но должен поддерживать версии ОС старше указанных выше, не может использовать обнуление слабых ссылок и, следовательно, должен использовать unsafe_unretained
слабые ссылки. Существует сторонняя библиотека под названием PLWeakCompatibility [1] , которая позволяет использовать обнуление слабых ссылок даже в этих старых версиях ОС.
Преобразование в
[ редактировать ]Xcode 4.2 или более поздней версии предоставляет возможность конвертировать код в ARC. [10] Начиная с Xcode 4.5, его можно найти, выбрав «Правка» > «Рефакторинг» > «Преобразовать в Objective-C ARC». Хотя Xcode автоматически преобразует большую часть кода, некоторый код, возможно, придется преобразовать вручную. Xcode сообщит разработчику, когда возникают более сложные случаи использования, например, когда переменная объявляется внутри пула автоматического выпуска и используется вне его, или когда два объекта необходимо соединить бесплатно с помощью специального приведения.
Быстрый
[ редактировать ]
В Swift ссылки на объекты являются сильными, если они не объявлены. weak
или unowned
. Swift требует явной обработки nil с необязательным типом: типом значения, который может иметь значение или быть нулевым. Необязательный тип должен обрабатываться путем «развертывания» его с помощью условного оператора , позволяющего безопасно использовать значение, если оно присутствует. И наоборот, любой необязательный тип всегда будет иметь значение и не может быть нулевым.
var myString: String // Can only be a string
var myOtherString: String? // Can be a string or nil
if let myString = myOtherString { // Unwrap the Optional
print(myString) // Print the string, if present
}
Соответственно, сильная ссылка на объект может быть как опционального, так и нефакультативного типа (необязательность и сила ссылки — это разные, хотя и связанные понятия). Слабая ссылка всегда имеет тип «Необязательная», поскольку объект можно освободить, а ссылку автоматически установить в ноль. Ссылки, не принадлежащие владельцу, подобны слабым ссылкам, но ARC не устанавливает их автоматически в нулевое значение. Они могут быть как необязательными, так и необязательными. Ожидается, что бесхозная ссылка всегда будет иметь значение, поэтому доступ к значению бесхозной ссылки после освобождения ссылочного экземпляра приведет к ошибке во время выполнения. [11]
var strongReference: MyClass // Strong non-Optional reference, cannot be nil
var strongOptionalReference: MyClass? // Strong Optional reference, can be nil (manually)
weak var weakReference: MyClass? // Weak reference, always Optional, can be nil (automatically or manually)
unowned var unownedReference: MyClass // Unowned non-Optional reference, cannot be nil
Swift также отличается от Objective-C использованием и поддержкой типов значений вместо ссылочных типов . Большинство типов в стандартной библиотеке Swift являются типами значений и копируются по значению, тогда как классы и замыкания являются ссылочными типами и передаются по ссылке. Поскольку типы значений копируются при передаче, они автоматически освобождаются, когда программа покидает область, в которой они содержатся. [11] [12]
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Сиракузы, Джон (20 июля 2011 г.). «Mac OS X 10.7 Lion: обзор Ars Technica» . Арс Техника . Арс Техника. В разделе «Автоматический подсчет ссылок» . Проверено 17 ноября 2016 г.
- ^ Кочан, Стивен Г. (2011). Программирование на Objective-C (4-е изд.). Бостон, Массачусетс: Аддисон-Уэсли. стр. 408 . ISBN 978-0321811905 .
- ^ Хоффман, Кевин (2012). Сэмс самостоятельно научится разработке приложений для Mac OS X Lion за 24 часа . Индианаполис, Индиана: Сэмс. стр. 73 . ISBN 9780672335815 .
- ^ "Общий" . Автоматический подсчет ссылок . LLVM.org . Проверено 15 августа 2012 г.
- ^ «Индекс доступности функций Objective-C» . Apple, Inc. Проверено 14 октября 2013 г.
- ^ Сакамото, Казуки (2012). Профессиональная многопоточность и управление памятью для iOS и OS X с помощью ARC, Grand Central Dispatch и Blocks . Апресс. стр. XII. ISBN 978-1430241164 .
- ^ Сиракузы, Джон (25 июля 2012 г.). «OS X 10.8 Mountain Lion: обзор Ars Technica» . Арс Техника . В разделе «Усовершенствования Objective-C» . Проверено 17 ноября 2016 г.
- ^ «Примечания к выпуску Xcode 8» . Разработчик Apple . 27 октября 2016. Архивировано из оригинала 19 марта 2017 года . Проверено 19 марта 2017 г.
- ^ Jump up to: а б с д и ж г час «Переход на примечания к выпуску ARC» . Проверено 14 сентября 2012 г.
- ^ «Что нового в Xcode 4.2 — автоматический подсчет ссылок» . Apple Inc. Архивировано из оригинала 20 августа 2012 года . Проверено 3 октября 2012 г.
- ^ Jump up to: а б «Автоматический подсчет ссылок — язык программирования Swift (Swift 5.7)» . docs.swift.org . Проверено 5 ноября 2022 г.
- ^ «Типы значений и ссылок» . Разработчик Apple . 15 августа 2014 года . Проверено 17 ноября 2016 г.
Внешние ссылки
[ редактировать ]- Переход на ARC – Библиотека разработчиков iOS
- «Автоматический подсчет ссылок» на языке программирования Swift