5

在以下代码中:

_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

请注意,我在 & 行之前直接使用这些变量作为左值...

在我没有错误地分配给它之后,它怎么能抱怨一个值不是左值?这是否与目标 C 创建的神奇 getter/setter 有关?

我想我需要解释一些上下文来解释我为什么要获取地址:

在我之前的 SO 帖子中,我展示了相同的代码,打印 %d 并发现在分配之后,由于某种原因,属性仍然为 0。所以,我想我会尝试获取属性的地址以查看它们的存储位置,也许我可以弄清楚为什么我没有成功分配给它们,然后就发生了这种情况。

我认为正如人们提到的那样,是的,可能是当我进行分配时,obj-c 会秘密地用调用 setter 代替它(然后是其他一些魔法,因为在另一篇 SO 帖子中,其他人提到了

BOOL b = [_imageView setHasVerticleScroller: YES]

失败,但是

BOOL b = _imageView.hasVerticalScroller = YES;

工作正常。

4

2 回答 2

3

我不是 100% 确定,但我会尝试回答。

这些属性都是BOOL类型,(我相信)是unsigned charObjective-C中的一个。(也许是一个int,我不记得了,但它是那样的。)所以你试图获取 ( &) 那些属性的地址。但是您实际上并没有直接访问 ivars;属性通过方法调用来获取它们的值。因此,您试图获取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);
于 2010-01-14T16:35:02.133 回答
2

_imageView.hasHorizontalScroller = YES;- 在这一行中,您访问 imageView 中的属性 - 所以您实际上并不访问值,而是调用setter方法:

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

在第二个示例中,您还可以访问属性,但这次 getter 方法被调用并返回 BOOL。因此,作为 mipadi 点,您不需要&在该 NSLog 语句中使用。

我建议阅读有关obj-c 中属性的文档。

编辑: 在这里你可以找到关于为什么属性在你提到的多个赋值语句中起作用的讨论:

BOOL b = _imageView.hasVerticalScroller = YES;
于 2010-01-14T16:40:01.533 回答