myView.frame.origin.x = value; 不起作用 - 但为什么?

All*_*one 31 struct objective-c variable-assignment declared-property

我知道我不能用这个:

myView.frame.origin.x = 25.0;
Run Code Online (Sandbox Code Playgroud)

而我必须使用它:

CGRect myFrame = myView.frame;
myFrame.origin.x = 25.0;
myView.frame = myFrame;
Run Code Online (Sandbox Code Playgroud)

而且我一直这样做,但我不知道为什么我必须这样做.我想在我的理解中填补这个空白.谁能解释一下?

如今Xcode为您提供"表达式不可分配".前一段时间你得到一个编译错误"Lvalue需要作为赋值的左操作数".

wal*_*lky 40

这里使用了两种不同的点语法.它们看起来一样,但它们根据它们的操作和使用它做了什么来做不同的事情:

  • 第一个myView.frame是速记[myView frame],一个按值返回CGRect结构的方法调用.
  • myFrame.origin.x 正在以传统的C方式访问普通的struct成员.
  • 第二个myView.frame也是速记,但由于该语句是一个赋值,它转换为调用另一个方法,[myView setFrame:myFrame].

在单行顶部示例中,您将获得rect的副本并设置它x,但不要将其复制回视图.你必须明确区分方法调用,点语法糖不能将它们魔术化为单个调用.

  • 很棒的解释! (2认同)

All*_*one 18

这不起作用的原因是由于两种语法的混合.
首先你有"." 作为调用访问器函数的快捷方式(Objective-C功能).所以

  • ab成为[getB];
  • ab = 5变为[setB:5];

然后theres"." 作为直接结构成员访问(纯C).所以

  • ab真的是ab;
  • ab真的是ab = 5;

在这样的设定值情况下将其组合起来是行不通的.
因为...如果你可以打电话

myView.frame.origin.x = 25.0;
Run Code Online (Sandbox Code Playgroud)
  • "myView.frame"部分等于[myView getFrame],你得到一个复制的CGRect框架(一个C结构)

  • "myView.frame.origin"为您提供了复制的CGRect的CGPoint原点(也是一个结构)

  • "myView.frame.origin.x = 25.0"为您提供了原始的CGFloat x,现在您想为其分配一些东西,这就是问题所在......

您尝试设置结构的结构的变量,这是可以的,但是没有从UIView到结构的指针,因此它被复制.所以你复制然后你设置然后你期望set动作以某种方式通过初始转到UIView转发,好吧,这只是不起作用.

当然你可能想知道为什么Apple还没有创建一个快捷方式,所以最后你复制的帧会自动重新注入一个自动附加的setFrame调用,我想你只需要了解它是如何实现的.

所以请记住,如果你得到一个指向框架的指针,它会工作,但是你没有,你会得到一个复制的结构.
因此,如果您期望myView.frame.origin.x = 25.0工作,您间接期望您的呼叫被自动翻译成某种形式
[myView setFrame:[myView getFrame:frame].origin.x = 25.0].
嗯,我想你可以承认这看起来不对劲.

还想象一下,如果你得到一个指向CGRect框架的直接指针并且你通过该指针改变某些东西,那么UIView将如何知道它的大小已经改变并且它必须自己更新?另一方面,如果进行[myView setFrame:newFrame]调用,则UIView可以执行所有必要的重新调整.