要接听subquestion,为什么你不能指定从getter返回一个结构组件: (作为一个动机,这是因为我看了这个问答几次。)
A.这有什么好用Cb-C做。这是C标准中规定的行为。你可以检查它的简单的C代码:
NSMakeSize(1.0, 2.0).width = 3.0; // Error
B.不,这是不的编译器的改进。如果是这样,警告将是结果,而不是错误。编译器开发人员不能自由决定错误是什么。 (有一些情况下,他们有自由,但这种明确提到。)
下这样做的原因错误是很容易的:
赋值表达式
NSMakeSize(1.0, 2.0).width
如果该表达式是l值,则
将是合法的。甲.
操作者的结果是L值,如果该结构是L值:
A postfix expression followed by the .
operator and an identifier designates a member of a structure or union object. The value is that of the named member,82) and is an lvalue if the first expression is an lvalue.
ISO/IEC 9899:TC3,6.5.2.3
因此这将是可分配的,如果表达式
NSMakeSize(1.0, 2.0)
是一个l值。不是这样。原因有点复杂。要明白,你必须知道.
,->
和&
之间的联系:
相反.
,->
始终是一个L值。
A postfix expression followed by the ->
operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue. 83)
因此 - 这就是脚注83解释 - ->
,&
,并且.
有一个链接:
如果你能计算具有与&
运营商C成分的结构S
的地址,表达式(&S)->C
相当于S.C
。这要求您可以计算地址S
。但你永远无法做到这一点与返回值,即使它是一个简单的整数...
int f(void)
{
return 1;
}
f()=5; // Error
...或...指针
int *f(void)
{
return NULL;
}
f()=NULL; // Error
你总是得到同样的错误:它是不可转让。因为它是一个r值。这是显而易见的,因为目前还不清楚,
a)编译器是否返回值的方式,无论他是否在地址空间中执行它。
b)中时的时间的返回值的使用寿命超过
再回到这意味着返回值是一个r值的结构。因此.
运算符的结果是一个r值。您不能为r值赋值。
D.解决方案
有一种解决方案分配给“返回的结构”。有人可能会决定,不管它是否好。由于->
总是一个l值,所以可以返回一个指向该结构的指针。取消引用此指针与->
运营商一贯的左值的结果,所以你可以赋值给它:
// obj.aIndex returns a pointer
obj.aIndex->category = 1;
你不需要@public
了点。 (真的是个坏主意)
我不遵循,为什么我不能只使用'obj.aIndex.category = 1;' – Wingzero
因为它会在对象的副本上设置新的类别' aIndex'(这样行就像我的第二个例子的前两行)。 – trojanfoe
我试过了,它会引发编译器错误,说'表达式不可分配'。看起来与你说的不一样? – Wingzero