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ę __strongpod 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_unretainedi __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 weaklub unsafe_unretained( assignjest to efektywne unsafe_unretained), a następnie dopasować ją, oznaczając odpowiednią zmienną wystąpienia za pomocą __weaklub __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_unretainedi __weakzapobiegają zatrzymywaniu obiektów, ale w nieco inny sposób. Ponieważ __weakwskaźnik do obiektu zostanie przekonwertowany nilna po cofnięciu alokacji obiektu, na który wskazuje, co jest bardzo bezpiecznym zachowaniem. Jak sama nazwa wskazuje, __unsafe_unretainedbę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_unretainedwtedy używać ? Niestety __weakjest 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_unretainedkwalifikatora lub użyć czegoś takiego jak MAZeroingWeakRef Mike'a Asha .
__unsafe_unretainedmoże być przydatny do definiowania tablic CNSStringstałych i tym podobnych, np.NSString __unsafe_unretained *myStrings = { @"Foo", @"Bar", @"Baz", nil };