/ / Избягването на „улавяне на себе си силно в този блок вероятно ще доведе до задържащ цикъл“ съобщение - цел-c, какао-докосване, какао, цел-c-блокове

Избягването на съобщението "Улавяне на силно в този блок е вероятно да доведе до задържане цикъл" съобщение - цел-в, какао-докосване, какао, обективи-C-блокове

всеки път, когато трябва да използвам глобален var или свойство в блок като този:

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

Трябва да пренапиша това като

BOOL *iis = isItSaving;
id myself = self;

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

или Xcode ще се оплаче "улавянето на себе си в този блок вероятно ще доведе до цикъл на задържане ...

Оплаква се дори от променливи BOOL?

Предекларирането на всичко преди даден блок изглежда куцо решение.

Това ли е правилният начин? Има ли елегантен начин?

Тези неща са грозни. Използвам ARC.

Отговори:

20 за отговор № 1

Проблемът възниква само при препращане self от блока, изрично или неявно. При достъп до глобални променливи не се издава предупреждение.

Във вашия случай вероятно сте имали достъп до (булев) ivar. Достъпът до ivar имплицитно използва self, затова "компилаторът ви предупреждава (правилно) за цикъл на задържане.

Общият начин за коригиране на цикъла на задържане е:

typeof(self) __weak weakSelf = self;

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

... и, да, това е малко грозна част от блокове.


4 за отговор № 2

употреба __unsafe_unretained typeof(self) weakSelf = self;


0 за отговор № 3

В допълнение към отговора на @NikolaiRuhe, във вашия пример при деклариране на свойствата

BOOL *iis = isItSaving;
id myself = self;

предполага strong препратки, така че използвайте __weak самостоятелно, за да предотврати цикъла на задържане. Тогава може да се чудите защо трябва да декларирате a __strong препратка към слабо себе си в рамките на блока и това "s, за да се уверите, че няма да бъде освободено по време на живота на блока, в противен случай weakSelf->isItSaving би се счупил, ако self бе освободен.