1

我无法理解下面的代码。它涉及带有 if 语句的 setter,该语句在执行之前要求 origin 变量为零(假)。

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) 不再为真,因为它已经包含上一个设置的非零值执行。尽管有这种逻辑,为什么它仍然执行?我错了吗?

4

2 回答 2

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。如果不是,请不要打扰,我们不需要或不想每次都创建一个新对象。但无论您是否必须创建对象或不,将其xy坐标设置为传入的坐标。

于 2013-07-03T12:30:48.350 回答
0

if 语句只检查 origin 是否存在,如果 origin 不存在,它会分配并初始化 origin,然后将值设置为方法参数中的值。

基本上这是一种方便的方法。第一次调用它时,如果需要,会创建原点,然后设置为 arg。

如果原点存在,那么它只是继续进行设置。

于 2013-07-03T04:47:34.450 回答