Im работает в чистой среде iOS5/ARC, поэтому я могу использовать ссылки __weak по мере необходимости. Я делаю ссылку на ivars в блоке во многих ситуациях, в первую очередь, на блоки анимации, которые перемещают представления вокруг, которые являются свойствами, например, моего класса контроллера представления.
Мой вопрос:
В самом тривиальном использовании ivars в блоке я создаю ссылочный цикл? Нужно ли использовать метод __weak self/strong self каждый раз, когда я пишу блок, который манипулирует переменными экземпляра содержащего объекта?
Я пересматривал сессию WWDC 2011 года № 322 (Objective-C Advancements in Depth), чтобы понять нюансы относительно 3-минутного сегмента, начинающегося со времени индекса 25:03 о "Reference Cycle Via Captured Self". Для меня это подразумевает, что любое использование иваров в блоке должно быть защищено с помощью слабой self/strong self setup, как описано в этом сегменте.
Пример метода ниже на контроллере просмотра типичен для анимаций, которые я делаю.
В блоке 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
}
Вот как Id переписывает кусок openIris с помощью руководства с сеанса № 322, но мне просто интересно, нужны ли все мои аналогичные блоки для этого слабого/сильного эталонного танца, чтобы обеспечить правильность и стабильность:
__weak MyClass *weakSelf = self;
void (^openIris)() = ^{
MyClass *strongSelf = weakSelf;
if (strongSelf) {
strongSelf.topView.frame = CGRectMake(....);
strongSelf.bottomView.frame = CGRectMake(....);
}
};
Действительно ли это необходимо?