предупреждение в примере кода PageControl: использование результата присваивания в качестве условия без скобок - PullRequest
0 голосов
/ 29 сентября 2011

Я пытаюсь понять, как работает UIPageControl. Я скачал этот пример кода от Apple UIPageControlSampleCode Он работает нормально, но есть предупреждение (Использование результата присваивания в качестве условия без скобок) в операторе if в следующем коде:

- (id)initWithPageNumber:(int)page 
{
    if (self = [super initWithNibName:@"MainView" bundle:nil])
    {
        pageNumber = page;
    }
    return self;
}

Теперь мой вопрос: зачем разработчику делать что-то подобное? сделать присваивание внутри условия оператора if? Это ошибка?

Ответы [ 2 ]

1 голос
/ 29 сентября 2011

Оператор присваивания (=), кроме выполнения присваивания, также возвращает присвоенное значение. Это так, что вы можете делать такие вещи, как

a = b = 1;

Что для компилятора совпадает с написанием

a = (b = 1);

Это означает, что при выполнении

self = <some init function>;

Вы можете проверить успешность инициализации, поместив присваивание в оператор if. Если это удалось, он возвращает действительный указатель, который не равен нулю, что означает, что условие оператора if истинно. Если инициализация завершается неудачно, она возвращает ноль, который фактически равен нулю, поэтому нет смысла продолжать оставшуюся инициализацию.

Причина предупреждения заключается в том, что легко использовать (=) в операторе if вместо (==):

if ( a = 1 ) // Should be a == 1
{
    // Do important stuff
}

Таким образом, компилятор пытается защитить вас от этой ошибки.

По этой причине я предпочитаю сделать условие явным, в вашем примере:

if ((self = [super initWithNibName:@"MainView" bundle:nil]) != nil)
0 голосов
/ 29 сентября 2011

Это предупреждение вызвано тем, что поскольку образец кода был создан Apple, версия компилятора и параметры компилятора по умолчанию изменились.

В частности, это предупреждение - которое говорит вам, что вы можете иметь в виду "== "вместо" = "(потому что оператор находится в условии" если "и вы обычно проверяете равенство вместо присваивания) - вполне логично;но предупреждение не было активировано по умолчанию в предыдущих версиях компилятора и Xcode , что объясняет, почему такой код все еще может присутствовать в старых образцах кодов (никто не совершенен, даже разработчики Apple;)) .

Тогда правильное нормальное использование / соглашение будет :

  • Либо явно проверить на равенство в "условие if, которое должно быть явным для компилятора, чтобы он был уверен в том, что вы имеете в виду: if (nil != (self = [super initWithNibName:@"MainView" bundle:nil]))
  • Или запись, которая также принимается компилятором, должна удвоить скобки упомянуть, что создание условия с простым присваиванием, а не "==", не является ошибкой.Таким образом, написание if ((self = [super initWithNibName:@"MainView" bundle:nil])) тоже сработает и уберет предупреждение.

Я бы предложил принять первое решение.Если вы явно проверили, что после назначения результат присваивания (таким образом, значение в self) не равно нулю, то когда вы читаете код (даже если он не ваш), вы уверены в том, что предполагалось.


Даже если код будет работать, если вы сохраняете код таким образом (и сохраняете предупреждение), это предупреждение гарантирует, что вы не набрали '=' вместо '=='в вашем коде, поскольку это может быть распространенной ошибкой (как для новичков, так и для опытных программистов, которые могли печатать слишком быстро;)), поэтому я считаю хорошей вещью, что теперь она активирована, и хорошей практикой явно делатьсравнение с нулем для ясности

...