我无法理解下面的代码。它涉及一个带有if语句的setter,它在执行前要求origin变量为零(false)。
if语句中的否定运算符要求 origin 为零(false)才能执行,在 origin 赋值后如何执行
。/**implementation file **/
-(void) setOrigin : (XYPoint *) pt
{
if (! origin)
origin = [[XYPoint alloc] init];
origin.x = pt.x;
origin.y = pt.y;
}
/** Main file **/
myPoint.x = 2;
myPoint.y = 3;
shape1.origin= myPoint;
myPoint.x = 2;
myPoint.y = 3;
shape1.origin= myPoint;
}
myRect.origin = myPoint;
^^第一次出现此方法时,执行该方法,因为实例变量为零且(!origin)有效。
但是,如果我在下一行更改myPoint的值并再次设置myRect.origin = myPoint,则setter方法不起作用,因为(!origin)不再为true,因为它已包含非零值先前的设置执行。尽管有这样的逻辑,为什么它仍然执行?我错了吗?
答案 0 :(得分:2)
您似乎对if
声明的范围感到困惑。无论空格如何,if
仅影响下一个语句。例如:
if(NO)
foo();
bar();
foo
未被调用,但bar
是;我已经正确地缩进了代码以强调这一点,但重要的是要意识到缩进甚至换行都不会对代码产生影响。我可以把上面的内容写成:
if(NO)foo();bar();
它将完全相同。因此,你必须注意空话;以下是一个常见错误:
if(NO);
foo();
bar();
你发现了这个问题吗? if(NO);
末尾的分号计为结束if
影响的(空)语句!这意味着foo()
将被执行,尽管它有误导性的缩进。我遇到的另一个问题是:
if(NO)
// foo();
bar();
你发现了这个吗? bar();
是if
之后的第一个语句,因此不会被调用!
大括号,无论其内容如何,都是单一(复合)语句,因此:
if(NO) {}
if(NO) {
foo();
}
if(NO) {
foo();
bar();
}
我认为这里没有任何意外:大括号内的所有内容都不会被执行,因为大括号及其所有内容都是单个语句。使用大括号可以防止我提到的两个错误,并清楚程序员的意图。出于这个原因,我建议总是使用大括号来明确你想要if
做什么。
在您的特定情况下:
if (! origin)
origin = [[XYPoint alloc] init];
origin.x = pt.x;
origin.y = pt.y;
你可以用括号重写if
以明确:
if (! origin) {
origin = [[XYPoint alloc] init];
}
origin.x = pt.x;
origin.y = pt.y;
这意味着“如果origin
还不是一个对象,请将其初始化为新的XYPoint
。如果没有,请不要打扰,我们不需要或者想要每个都创建一个新对象但无论您是否必须创建对象,都要将其x
和y
坐标设置为传入的坐标。
答案 1 :(得分:0)
if语句只检查原点是否存在,如果origin不存在,则在将值设置为method参数的值之前,它会分配并初始化origin。
基本上这是一种方便的方法。 第一次调用它时,如果需要则创建原点,然后设置为arg。
如果原点存在,那么它只是继续进行设置。