在一个钢琴应用中,我正在分配黑键的坐标。以下是导致错误的代码行。
'blackKey'和'whiteKey'都是自定义视图。
'blackKey'和'whiteKey'都是自定义视图。
blackKey.center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
blackKey.center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
blackKey.center.x
时,blackKey.center
和 center.x
都看起来像结构成员访问,但它们实际上是完全不同的东西。 blackKey.center
是一个属性访问,它会被转换为类似 [blackKey center]
这样的东西,然后再转换为类似 objc_msgSend(blackKey, @selector(center))
这样的东西。您无法修改函数的返回值,例如 objc_msgSend(blackKey, @selector(center)).x = 2
— 因为返回值未存储在任何有意义的位置,所以这只是没有意义的。因此,如果您想修改结构体,您需要将属性的返回值存储到变量中,修改变量,然后将属性设置为新值。anObject.anNonStructProperty.anProperty = someValue
,对吧?那么如何表达我们不能修改函数的返回值呢?你能解释一下吗? - EmptyStackanObject.someProperty = something
时,它不等同于[anObject someProperty] = something
,而是等同于[anObject setSomeProperty:something]
。你正在向对象发送一条消息,调用一个setter方法。你并没有给这个方法的返回值赋值。出现赋值的外观只是语法糖,就像成员访问的外观是一个getter方法的语法糖一样。 - ChuckblackKey.center
内部调用的是 objc_msgSend(blackKey, @selector(setCenter:))
而不是 objc_msgSend(blackKey, @selector(center))
对吗? - AdithyablackKey.center
调用了setCenter:
,那么你认为参数是什么?[blackKey setCenter: ?????]
。实际上只是[blackKey center]
。 - Chuck如果一个CGPoint
是对象的属性,你不能直接更改它的x
值(或者结构体的任何值),需要使用以下方法:
CGPoint _center = blackKey.center;
_center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
blackKey.center = _center;
blackKey.center = CGPointMake ( whiteKey.frame.origin.x + whiteKey.frame.size.width, blackKey.center.y);
一种方法。
根据其含义,您不能为表达式赋值。例如,a + b = c是被禁止的。
使用宏的一种替代方案:
#define CGPOINT_SETX(point, x_value) { \
CGPoint tempPoint = point; \
tempPoint.x = (x_value); \
point = tempPoint; \
}
#define CGPOINT_SETY(point, y_value) { \
CGPoint tempPoint = point; \
tempPoint.y = (y_value); \
point = tempPoint; \
}
CGPOINT_SETX(blackKey.center, whiteKey.frame.origin.x + whiteKey.frame.size.width);
或稍微简单一些:
CGPOINT_SETX(blackKey.center, CGRectGetMaxX(whiteKey.frame));
do ... while(0)
吗?使用块作用域 { ... }
能否足以声明临时变量(避免与外部定义的变量重名),并确保内部语句只执行一次? - Nicolas Miarido ... while(0)
这种方式已经很长时间了,以至于我没意识到 {...}
块也能很好地工作。谢谢,让代码更简洁了。 - ThomasWdo ... while(0)
的原因在这里:https://dev59.com/qXVC5IYBdhLWcg3w4Vb6 对于我的情况来说并不是必要的,但有些情况下是必须的。 - ThomasW
whiteKey.frame.origin.x + whiteKey.frame.size.width
与CGRectGetMaxX(whiteKey.frame)
是相同的。 - ThomasW