Kompilator LLVM 3.0 wprowadza cztery nowe kwalifikacyjne własności: __strong
, __autoreleasing
, __unsafe_unretained
, i __weak
. Pierwsze trzy są dostępne nawet poza ARC, zgodnie ze specyfikacją .
Jak wskazuje Joshua, domyślnie zakłada się, że wszystkie wskaźniki znajdują się __strong
pod ARC. Oznacza to, że gdy obiekt jest przypisany do tego wskaźnika, jest on zachowywany tak długo, jak długo ten wskaźnik się do niego odnosi. Jest to dobre dla większości rzeczy, ale otwiera możliwość zachowania cykli, jak opisuję w mojej odpowiedzi tutaj . Na przykład, jeśli masz obiekt, który zawiera inny obiekt jako zmienną wystąpienia, ale ten drugi obiekt ma silne łącze z powrotem do pierwszego jako jego delegat, te dwa obiekty nigdy nie zostaną zwolnione.
Z tego powodu istnieją kwalifikatory __unsafe_unretained
i __weak
. Najczęściej są używane w przypadku delegatów, w przypadku których należy zdefiniować właściwość dla tego delegata za pomocą atrybutu weak
lub unsafe_unretained
( assign
jest to efektywne unsafe_unretained
), a następnie dopasować ją, oznaczając odpowiednią zmienną wystąpienia za pomocą __weak
lub __unsafe_unretained
. Oznacza to, że zmienna wystąpienia delegata nadal będzie wskazywać z powrotem na pierwszy obiekt, ale nie spowoduje zachowania tego obiektu, przerywając w ten sposób cykl przechowywania i umożliwiając zwolnienie obu obiektów.
Poza delegatami jest to przydatne do przerwania wszelkich innych cykli przechowywania, które mogą powstać w kodzie. Narzędzie Leaks zawiera teraz widok Cykle, który przedstawia w sposób graficzny cykle zatrzymania wykryte w aplikacji.
Obie __unsafe_unretained
i __weak
zapobiegają zatrzymywaniu obiektów, ale w nieco inny sposób. Ponieważ __weak
wskaźnik do obiektu zostanie przekonwertowany nil
na po cofnięciu alokacji obiektu, na który wskazuje, co jest bardzo bezpiecznym zachowaniem. Jak sama nazwa wskazuje, __unsafe_unretained
będzie nadal wskazywać pamięć, w której znajdował się obiekt, nawet po zwolnieniu go. Może to prowadzić do awarii z powodu dostępu do tego zwolnionego obiektu.
Dlaczego miałbyś __unsafe_unretained
wtedy używać ? Niestety __weak
jest obsługiwany tylko w systemach iOS 5.0 i Lion jako cele wdrożenia. Jeśli chcesz wrócić do iOS 4.0 i Snow Leopard, musisz użyć __unsafe_unretained
kwalifikatora lub użyć czegoś takiego jak MAZeroingWeakRef Mike'a Asha .
__unsafe_unretained
może być przydatny do definiowania tablic CNSString
stałych i tym podobnych, np.NSString __unsafe_unretained *myStrings = { @"Foo", @"Bar", @"Baz", nil };