свойство не устанавливается после ленивой инициализации target-c

У меня есть свойство BOOL, и в начале это свойство равно NO. Я хочу установить для этого свойства значение YES с самого начала моей программы, но с возможностью переключения. Для этого я сделал этот геттер:

-(BOOL)turn
{
    if(!_turn)
        _turn = YES;
    return _turn;
}

Этот геттер установил для моего свойства поворота значение YES, но он делает его «постоянным», всегда YES. Почему?

я думал

if(!_turn)

конструкция специально по той причине, что вы хотите установить значение объекта «еще не установлено»

Можете ли вы ответить мне, почему это так? И как я могу установить значение моего свойства на то, что я хочу. Спасибо.


person Dima Deplov    schedule 18.04.2013    source источник
comment
Вопрос не ясен...   -  person Bhanu Prakash    schedule 18.04.2013
comment
@BhanuPrakash после этого геттера я не могу установить для свойства поворота значение НЕТ. Например: self.turn = !self.turn; результат будет ДА ​​из-за геттера, я думаю, но почему?   -  person Dima Deplov    schedule 18.04.2013


Ответы (2)


Посмотрите на свою таблицу действий:

turn:     False          True
!turn   turn = YES      Do Nothing

Когда _turn ложно, вы переворачиваете его слишком верно. Когда _turn истинно, вы ничего не делаете (нет оператора else). Затем вы возвращаете значение _turn. Так что да, вы возвращаете true во всех случаях.

Честно говоря, дизайн не очень. Если вы хотите установить начальное значение переменной в определенное значение, сделайте это в методе init. Затем предоставьте другой метод, который просто переключает значение:

-(BOOL) toggleTurn {
  _turn = !_turn;
  return _turn;
}
person Perception    schedule 18.04.2013

Обычно метод ленивой инициализации используется с указателями на объекты, а не с примитивными типами. Это связано с тем, что BOOL имеет только два возможных состояния: NO и YES, не существует "неопределенного состояния", которое обычно ассоциируется с < em>nil для объектов.

Причина, по которой он не переключается, заключается в том, что вы не переключаете его, а просто устанавливаете для него значение ДА, когда оно равно НЕТ, но вы не обрабатываете случай, когда он равен YES. Если вы хотите переключить его, просто сделайте это:

-(BOOL)turn
{
    return _turn= !_turn;
}

PS: Кто бы мог возразить, что ваш метод не является геттером, потому что вы изменяете переменную перед ее возвратом. Поэтому я предлагаю просто вернуть _turn, не переключая его, и создать еще один отдельный метод для переключения переменной.

Также я хотел бы упомянуть, что то, что вы делаете, не называется ленивой инициализацией, я покажу вам случай ленивой инициализации:

// In the interface:
@property(nonatomic,readonly) NSNumber* turnObject;
// In newer compiler versions it should be auto synthesized to _turnObject

// In the implementation: 
-(BOOL) turn
{
    // In this case I am not toggling it
    if(!_turnObject)        // Equal to if(turnObject==nil)
        _turnObject= @(NO); // Equal to _turnObject=[NSNumber numberWithBOOL: NO];
    return _turnObject;
}
person Ramy Al Zuhouri    schedule 18.04.2013