ARC, ivars в блоках и циклах ссылок с помощью захваченного себя

Я работаю в чистой среде 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(....);
     }
};

Это действительно необходимо?

26
задан Brad Larson 4 November 2011 в 16:16
поделиться

1 ответ

Дело, о котором стоит беспокоиться, примерно как addObserverForName:object:queue:usingBlock:. Документы говорят: «Блок копируется центром уведомлений». В ARC это слово «копия» является красным флагом; Теперь вам нужно принять меры, чтобы вы (абонент) не протекали.

РЕДАКТИРОВАТЬ: Кроме того, иногда сама ARC будет предупреждать вас. Блок завершения -[UIPageViewController setViewControllers:direction:animated:completion:] является показательным примером. Я бы никогда не заподозрил, что использование self здесь может привести к циклу сохранения, но ARC предупредил, что это произойдет, поэтому я на всякий случай исполнил слабосильный танец.

4
ответ дан 28 November 2019 в 07:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: