Я работаю в чистой среде iOS5 / ARC, поэтому я могу использовать __weak ссылки по мере необходимости. Я ссылаюсь на ivars в блоке во многих ситуациях, в первую очередь на блоки анимации, которые перемещают представления, которые являются свойствами, скажем, моего класса контроллера представления.
При простейшем использовании ivars в блоке создаю ли я ссылочный цикл? Нужно ли мне использовать технику __weak self / strong self каждый раз , когда я пишу блок, который манипулирует переменными экземпляра содержащего объекта?
Я повторно смотрел сессию WWDC 2011 № 322 (цель -C Подробные сведения), чтобы понять нюансы, касающиеся 3-минутного сегмента, начинающегося с временного индекса 25:03, о «Контрольном цикле с помощью захваченного себя». Для меня это означает, что любое использование ivars в блоке должно быть защищено с помощью слабой самостоятельной / сильной самостоятельной настройки, как описано в этом сегменте.
Приведенный ниже пример метода для контроллера представления типичен для анимаций, которые я делаю.
В блоке openIris неправильно ссылаться на ivars «_topView» и «_bottomView», как у меня?
Должен ли я всегда устанавливать __weak ссылку на себя перед блоком, а затем сильную ссылку внутри блока на Слабая ссылка просто настраивается заранее, а затем получает доступ к ivars через эту сильную ссылку в моем блоке?
Из сеанса WWDC я понимаю, что ссылка на ivars в блоке действительно создает ссылку на подразумеваемую личность, от которой эти ivars зависают .
Для меня это означает, что на самом деле нет какого-либо простого или тривиального случая, когда было бы правильно получить доступ к иварам в блоке без танца слабый / сильный, чтобы гарантировать отсутствие циклов. Или я слишком много читаю в угловом случае, который неприменим к простым случаям, таким как мой пример?
- (void)openIrisAnimated:(BOOL)animated
{
if (_isIrisOpened) {
NSLog(@"Asked to open an already open iris.");
return; // Bail
}
// Put the common work into a block.
// Note: “_topView” and “_bottomView” are the backing ivars of
// properties “topView” and “bottomView”
void (^openIris)() = ^{
_topView.frame = CGRectMake(....);
_bottomView.frame = CGRectMake(....);
};
// Now do the actual opening of the iris, whether animated or not:
if (animated) {
[UIView animateWithDuration:0.70f
animations:^{
openIris();
}];
}
else {
openIris();
}
_irisOpened = YES; // Because we have now just opened it
}
Вот как я бы переписал часть блока openIris, используя руководство из Сессии № 322, но я ' Мне просто интересно, требуется ли для всех моих подобных блоков этот слабый / сильный эталонный танец для обеспечения правильности и стабильности:
__weak MyClass *weakSelf = self;
void (^openIris)() = ^{
MyClass *strongSelf = weakSelf;
if (strongSelf) {
strongSelf.topView.frame = CGRectMake(....);
strongSelf.bottomView.frame = CGRectMake(....);
}
};
Это действительно необходимо?
Дело, о котором стоит беспокоиться, примерно как addObserverForName:object:queue:usingBlock:
. Документы говорят: «Блок копируется центром уведомлений». В ARC это слово «копия» является красным флагом; Теперь вам нужно принять меры, чтобы вы (абонент) не протекали.
РЕДАКТИРОВАТЬ: Кроме того, иногда сама ARC будет предупреждать вас. Блок завершения -[UIPageViewController setViewControllers:direction:animated:completion:]
является показательным примером. Я бы никогда не заподозрил, что использование self
здесь может привести к циклу сохранения, но ARC предупредил, что это произойдет, поэтому я на всякий случай исполнил слабосильный танец.