2012-11-06 12 views
10

Jaki jest właściwy sposób dodawania obiektów w NSMutableArray, który jest silnie zdefiniowany przez właściwość.Jaki jest właściwy sposób na uniknięcie zatrzymania cyklu podczas korzystania z bloków

[tapBlockView setTapBlock:^(UIImage* image) { 
    [self.myImageArray addObject:image]; // self retain cycle 
} 

Jeśli będę tworzyć słabe odniesienia coś podobnego

__weak NSMutableArray *array = self.myImageArray; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [array addObject:image]; // If I will do this then how will I update original Array ? 
} 

Próbowałem również

__weak id weakSelf = self; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [weakSelf storeImageInaNewMethod:image]; // Calling SToreImageInaNewMethod 
} 

i

-(void)storeImageInaNewMethod:(UIImage*)image { 
    [self.myImageArray addObject:image]; // This again retaining cycle 
} 

Jaki jest właściwy sposób zaktualizować oryginalnego obiektu zdefiniowane przez właściwość?

+0

Bloki funkcji pointers.Can't jak właśnie ustawionego bloku do zera, jeśli nie Potrzebujesz tego już? –

Odpowiedz

8

Spróbuj kombinacji 2 i 3.

__weak id weakSelf = self; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [weakSelf.myImageArray addObject:image]; 
} 
+0

Pamiętaj, że jest to ważne tylko wtedy, gdy użyjesz weakSelf w pierwszym wierszu bloku, jeśli zrobisz cokolwiek innego, wtedy potrzebujesz odpowiedzi Kaana. – malhal

0

Twoje drugie i trzecie wyglądają poprawnie. Drugi działa, ponieważ nie utworzyłeś kopii tablicy, więc nadal wskazuje na oryginalną. Trzeci działa, ponieważ odniesienie do siebie jest słabe.

+0

Druga działa tylko wtedy, gdy 'self.myImageArray' zwraca bezpośrednie odniesienie do ivar. To może nie być bezpieczne założenie. – rmaddy

+0

To prawda, że ​​jest to dobry punkt. –

12

Po odpowiedź Maddy - to jest od 2012 WWDC wykład na GCD i asynchronicznego programowanie:

__weak MyClass *weakSelf = self; 

[tapBlockView setTapBlock:^(UIImage* image) { 
    __strong MyClass *strongSelf = weakSelf; 
    if(strongSelf) { 
     [strongSelf.myImageArray addObject:image]; 
    } 
}]; 
+0

Nie rozumiem, dlaczego znowu zmieniasz się w __strong? Chyba tylko ten kod jest wystarczający? [weakSelf.myImageArray addObject: image]; – Tariq

+6

Powodem odesłania do '__strong' jest zagwarantowanie, że jeśli' weakSelf' będzie nadal żył, gdy zostanie wykonany pierwszy wiersz bloku, będzie on nadal funkcjonował do końca wykonywania bloku. –

+0

Jeśli włączyłeś ostrzeżenia, zobaczysz, dlaczego __strong jest potrzebny: słaby zmienny może zniknąć w dowolnym momencie, w tym w środku połączenia weakSelf.myImageArray, co z pewnością spowoduje problemy. – gnasher729

1

w twoim przypadku trzeba tylko odwoływać tablicę, która odwołuje się self tak:

NSMutableArray *array = self.myImageArray; 
[tapBlockView setTapBlock:^(UIImage* image) 
          { 
          [array addObject:image]; // No cycle 
          }]; 

Działa dobrze pod warunkiem że self.myImageArray nie zwraca różnych odwołań do tablic przy różnych Czasy ent. Nie ma cyklu: bieżący obiekt odwołuje się do tablicy i bloku, a ten blok odwołuje się do tablicy.

Jeśli self.myImageArray robi zwracać różne odwołania do tablic jako różne czasy następnie wykorzystać słabe odniesienie do self, sprawa 3.

Powiązane problemy