33

Załóżmy, że już tworzyć słaby siebie korzystającOdnosząc się do słabego siebie wewnątrz zagnieżdżonego bloku

__weak typeof(self) weakSelf = self; 
[self doABlockOperation:^{ 
     ... 
    }]; 

wewnątrz tego bloku, gdybym gnieździe inny blok:

[weakSelf doAnotherBlockOperation:^{ 
      [weakSelf doSomething]; 
} 

stworzy cykl zatrzymania? Czy muszę utworzyć kolejne słabe odniesienie do weakSelf?

__weak typeof(self) weakerSelf = weakSelf; 
[weakSelf doAnotherBlockOperation:^{ 
       [weakerSelf doSomething]; 
    } 

Odpowiedz

19

To zależy.

Tworzysz tylko cykl zatrzymania, jeśli rzeczywiście przechowujesz blok (ponieważ self wskazuje na blok i blokuje punkty do self). Jeśli nie zamierzasz przechowywać żadnego z bloków, użycie silnego odniesienia do self jest wystarczająco dobre - blok zostanie zwolniony pierwszy po jego wykonaniu, a następnie zwolni jego wskaźnik na self.

W tym konkretnym przypadku, chyba że wykonujesz więcej operacji, które nie są wyświetlane, nie musisz tworzyć żadnych słabszychWeakerEvenWeakerSelfs.

+0

Rozumiem więc, że część dotycząca słabego ja jest potrzebna, jeśli na przykład samo zachowuje blok. Ale jakie operacje mogę wykonać, że będę potrzebował słabszegoSelfa? –

+0

Właściwie, myślę, że nigdy nie będziesz potrzebował "słabszych elementów" - słaby wskaźnik jest oznaczony jako nie zwiększający liczby odnośników, a zatem nie ma sposobu, aby uczynić go "słabszym". –

55

Twój kod będzie działał poprawnie: słabe odniesienie nie spowoduje zatrzymania cyklu, ponieważ wyraźnie nakazujesz ARC, aby nie zwiększał wartości retaincount swojego słabego obiektu. Aby uzyskać najlepszą praktykę, powinieneś jednak utworzyć silne odwołanie do obiektu za pomocą słabego. To nie utworzy cyklu zatrzymania, ponieważ silny wskaźnik w bloku będzie istniał tylko do momentu zakończenia bloku (jego zasięg to tylko sam blok).

__weak typeof(self) weakSelf = self; 
[self doABlockOperation:^{ 
    __strong typeof(weakSelf) strongSelf = weakSelf; 
    if (strongSelf) { 
     ... 
    } 
}]; 
+1

Czy możesz podać więcej szczegółów lub podać kilka linków o tym, dlaczego powinienem utworzyć silne odniesienie do mojego obiektu używając słabego? 1 lub 2 praktyczne przypadki bardzo by pomogły. Dzięki. –

+2

Dobrą rzeczą jest to, że można bezpiecznie sprawdzić pogodę, czy obiekt nadal istnieje po wykonaniu bloku. W przeciwnym razie będziesz dzwonił zero, co oznacza, że ​​twój blok nie zrobi zbyt wiele. Radzę ci oglądać [ten film z WWDC 2012] (https://developer.apple.com/videos/wwdc/2012/?id=712);). –

+1

@EnzoTran: chcesz utworzyć silne odniesienie, ponieważ słabe odniesienie jest "bezpieczne" tylko dlatego, że wiesz, że 'self' nadal będzie prawidłowym obiektem przed wykonaniem bloku. Ale nie ma gwarancji, że nie zostanie zwolniony przez czas wykonania bloku wewnętrznego, dlatego powinien uchwycić silne odniesienie. – newacct