2013-07-12 4 views
0

Я видел следующий код в WWDC 2011- Session 322 Objective-C улучшению Глубиныслабая ссылка причиной аварии ошибка

-(void) startBlinker{ 
    __weak MyClass * weakSelf = self; 

    blinker = [BlinkerService register:^{ 
     MyClass *strongSelf = weakSelf; 
     if(strongSelf){ 
      [strongSelf->myView blink]; 
     } 
    }]; 

} 

Я думаю, что смогу осуществить это просто проверить weakSelf как

if(weakSelf){ 
    [weakSelf->myView blink]; 
} 

почему код использует strongSelf?

+0

Причина в том, что weakSelf может стать 'nil' после того, как вы проверите, является ли это' nil' и перед вами доступ к его iView. Создав для этого ссылку на стек, вам гарантируется, что объект будет сохраняться до тех пор, пока не будет использован последний синтаксис ссылки (время, определенное ARC). –

+0

спасибо, пожалуйста, ответьте на этот вопрос, и я приму его. можете ли вы сказать мне, когда приложение может потерпеть крах, потому что доступ к объекту nil? потому что отправить сообщение в nil не будет crash – NOrder

+1

Код 'weakSelf-> myView' не отправляет сообщение' weakSelf', он использует оператор разыменования '->'. 'weakSelf-> myView' эквивалентно' (* weakSelf) .myView'; в результате, если 'weakSelf' является' nil', мы будем разыскивать 'NULL' (напомним, что' nil' и 'NULL' - это нулевой адрес) и аварийный. –

ответ

2

Если объект, имеющий слабые опорные точки, освобождается, слабое задание оценивается равным нулю. Вызов методов на nil - это нормально, но доступ к полям с помощью оператора стрелки не выполняется. Поэтому вы должны убедиться, что указатель не равен нулю, прежде чем обращаться к полю с помощью указателя стрелки.

if(weakSelf){ // no weak sheeps this week 
    // weakSelf may get deallocated at this point. 
    // In that case the next line will crash the app. 
    [weakSelf->myView blink]; 
} 

Сильное «я» гарантирует, что «я» не будет освобождено между операторами if и операторами блока if.

1

Обычно слабая ссылка выполняется так, чтобы избежать удержания циклов в блоках. Блоки сохраняют «я», что вызывает цикл сохранения, если вы пытаетесь получить доступ к сильной ссылке на себя. Таким образом, вы создаете слабое «я» вне блока и обращаетесь к нему внутри блока, чтобы избежать цикла сохранения.

0

Ахмед Мохаммед является правильным, однако другое возможное решение объявить MyView как собственность, а не как Ивар и сделать это:

-(void) startBlinker{ 
    __weak MyClass * weakSelf = self; 

    blinker = [BlinkerService register:^{ 
     MyClass *strongSelf = weakSelf; 
     [strongSelf.myView blink]; 
    }]; 

} 

Таким образом, вы на самом деле не волнует, если strongSelf равна нулю или нет.

Смежные вопросы