Разве «LValue» не означает то, что я думаю? - PullRequest
5 голосов
/ 14 января 2010

В следующем коде:

_imageView.hasHorizontalScroller = YES;
_imageView.hasVerticalScroller = YES;
_imageView.autohidesScrollers = YES;

NSLog(@"scrollbar? H %p V %p hide %p", 
      &(_imageView.hasHorizontalScroller), 
      &(_imageView.hasVerticalScroller),
      &(_imageView.autohidesScrollers));

Я получаю ошибку:

Controller.m:143: error: lvalue required as unary '&' operand
Controller.m:144: error: lvalue required as unary '&' operand
Controller.m:145: error: lvalue required as unary '&' operand

Обратите внимание, что я ИСПОЛЬЗУЮ эти переменные как lvalues ​​непосредственно перед & строк ...

Как можно жаловаться, что значение не является lvalue сразу после того, как я присвоил ему значение без ошибки? это связано с магическими геттерами / сеттерами, которые создает цель C?

Я думаю, мне нужно объяснить контекст, чтобы объяснить, ПОЧЕМУ я пытаюсь получить адрес:

в моем предыдущем сообщении SO я показал тот же код, напечатал% d и обнаружил, что после назначений свойства по какой-то причине все еще были равны 0. Итак, я решил, что я попытаюсь получить адреса свойств, чтобы увидеть, где они хранятся, и, возможно, я смогу понять, почему я не назначаю их успешно, и тогда это произошло.

Я думаю, что, как уже упоминали люди, да, возможно, когда я делаю задание, obj-c тайно заменяет это вызовом установщика (а затем каким-то другим волшебством, потому что в другом сообщении SO, кто-то еще упомянул,

BOOL b = [_imageView setHasVerticleScroller: YES]

терпит неудачу, но

BOOL b = _imageView.hasVerticalScroller = YES;

отлично работает.

Ответы [ 2 ]

3 голосов
/ 14 января 2010

Я не уверен на 100%, но я собираюсь сделать удар в ответ.

Все эти свойства являются BOOL типами, что (я считаю) unsigned char в Objective-C. (Может быть, int, я не могу вспомнить, но это что-то вроде этого.) Итак, вы пытаетесь получить адрес (&) этих свойств. Но вы на самом деле не получаете доступ к иварам напрямую; свойства проходят через вызов метода, чтобы получить их значения. Таким образом, вы пытаетесь получить адрес BOOL возвращаемого значения метода, но поскольку вы на самом деле не присваиваете значение для , адрес отсутствует - вы просто получаете значение .

У вас возникла бы такая же проблема, если бы вы сделали это:

static int returnOne(void)
{
    return 1;
}

// Later...

NSLog(@"returnOne is %p", &returnOne());    // Oops, the return value of returnOne has no address!

Ваш журнал вызовов должен выглядеть следующим образом:

NSLog(@"scrollbar? H %d V %d hide %d", 
  _imageView.hasHorizontalScroller, 
  _imageView.hasVerticalScroller,
  _imageView.autohidesScrollers);
2 голосов
/ 14 января 2010

_imageView.hasHorizontalScroller = YES; - в этой строке вы получаете доступ к свойству в imageView - поэтому вы на самом деле не получаете доступ к значению, а вызываете setter метод:

[_imageView  setHasHorizontalScroller:YES]; // Equivalent of your code.

Во втором примере вы также получаете доступ к свойству, но на этот раз вызывается метод getter и возвращает BOOL. Так что, как мипади, вам не нужно использовать & в этом операторе NSLog.

Я бы предложил прочитать документы о свойствах в obj-c.

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

BOOL b = _imageView.hasVerticalScroller = YES;
...