2013-04-17 9 views
10

za każdym razem muszę użyć globalnego var lub właściwość wewnątrz bloku jak ten:Unikanie „Przechwytywanie siebie mocno w tym bloku może doprowadzić do zatrzymania cyklu” wiadomości

self.save = ^(){ 
    if (isItSaving == NO) { 
     [self saveMyFile]; 
    } 
}; 

mam do przerobienia to jak

BOOL *iis = isItSaving; 
id myself = self; 

self.save = ^(){ 
    if (iis == NO) { 
     [myself saveMyFile]; 
    } 
}; 

lub Xcode będzie narzekać „przechwytywanie siebie mocno w tym bloku może doprowadzić do zatrzymania cyklu ...

zarzuca nawet o zmiennych BOOL?

Redeclaring wszystko przed blok wydaje się być kiepskim rozwiązaniem.

Czy to prawda? Czy istnieje elegancki sposób?

To jest brzydkie. Używam ARC.

Odpowiedz

20

Problem występuje tylko w przypadku odwołania się do self z poziomu bloku, jawnie lub niejawnie. Nie ma żadnego ostrzeżenia emitowanego podczas uzyskiwania dostępu do zmiennych globalnych.

W twoim przypadku prawdopodobnie uzyskałeś dostęp do (boolean) ivar. Dostęp do ivar domyślnie używa self, dlatego kompilator ostrzega (poprawnie) o cyklu zatrzymania.

Wspólna sposób ustalić cykl zatrzymania jest:

typeof(self) __weak weakSelf = self; 

self.save = ^() { 
    typeof(weakSelf) __strong strongSelf = weakSelf; 
    if (strongSelf != nil && ! strongSelf->isItSaving) { 
     [strongSelf saveMyFile]; 
    } 
}; 

... i tak, że to trochę brzydki części bloków.

+1

człowiek, to jest brzydkie jak diabli. Konieczność redeclare wszystko ... dzięki. – SpaceDog

+0

@MarkAmery Tak, clang łapie coraz więcej problemów. I prawdą jest, że czas życia otaczającego obiektu powinien zostać przedłużony przynajmniej do momentu, aż blok się skończy. Edycja ... –

+1

@NikolaiRuhe * "czas życia otaczającego obiektu powinien zostać przedłużony przynajmniej do momentu, gdy blok się skończy" * - miłe, nie zauważyłem z początku żadnego powodu, dla którego stworzenie silnego odniesienia do "siebie" w bloku byłoby lepiej używać '__unsafe_unretained', ale sama fraza czyni to niesamowicie czystym. Może nawet warto porównać dwa podejścia w twojej odpowiedzi, jeśli chcesz. –

4

Zastosowanie __unsafe_unretained typeof(self) weakSelf = self;

+0

Myślę, że nie można używać __unsafe_unretained z ARC – SpaceDog

0

Oprócz @ odpowiedzi NikolaiRuhe jest w swojej przykład podczas deklarowania właściwości

BOOL *iis = isItSaving; 
id myself = self; 

implikuje strong referencje, więc używaj __weak siebie, aby zapobiec cykl zatrzymania. Wtedy możesz się zastanawiać, dlaczego musisz zadeklarować odniesienie do słabego ja w bloku, a to by upewnić się, że nie zostanie uwolnione podczas życia bloku, w przeciwnym razie weakSelf->isItSaving pęknie, jeśli zostanie zwolniony self.

Powiązane problemy