点表示法与方法表示法

时间:2012-07-08 20:06:36

标签: objective-c ios ios5

我正在深入研究iOS编程,而我很难理解Dot Notation和Method Notation。

据我了解,Dot Notation可用于在属性上调用setter / getter,并且写入/读取更清晰。方法表示法用于向对象发送消息以操纵它们等。

有人可以给我一个简单的解释,说明为什么以下两个语句本质上是不同的,一个会编译,但另一个会因语法错误而失败。

- (IBAction)digitPressed:(UIButton *)sender 
{
   NSString *digit = [sender currentTitle];

   self.display.text = [self.display.text stringByAppendingFormat:digit];
   self.display.text = self.display.text.stringByAppendingFormat:digit;

}

感谢。

6 个答案:

答案 0 :(得分:12)

您正在使用新语法使用旧语法的有趣时间进入Objective-C开发。点语法是语法糖,在某些情况下你可以使用它,但你不应该。

以下是无效的语法。你使用冒号的任何东西(除了镶嵌者或吸气剂),你都不会使用点符号。

self.display.text = self.display.text.stringByAppendingFormat:digit;

另外,您可以使用stringByAppendingString,而不是stringByAppendingFormat

您使用点符号来访问变量,而不是调用会产生影响的操作。

<强>正确:     self.foo.attributeOfMyClass

<强>不正确:     self.foo.downloadSomethingFromAWebsite

确保总是使用点符号来访问属性值,并且总是使用括号表示法(即使你不必须)来调用操作方法,代码一目了然会更加清晰。

答案 1 :(得分:5)

点符号只是一种特定方法的简写 - 即访问者。您可以在以下情况下使用它:

  1. 设置属性时:foo.bar = 3;相当于[foo setBar:3];
  2. 申请财产时:除上述财产外,foo.bar相当于[foo bar]
  3. 点符号只是 的简写 - 它与属性的关系没有任何魔力。您可以理论上使用点符号发送任何不带参数的消息(foo.doSomething),但这将是非常非常糟糕的样式,因为点符号是打算的对于属性。另请注意,如果点符号与方括号在您学习时让您感到困惑,那么完全避免使用点符号是完全有效的选择。如果您愿意,它只是可能用于访问者的一种捷径。

答案 2 :(得分:3)

实际上,你的第二个陈述是不正确的。 Objective C调用方法(消息)的方法是使用[instance message]语法。 正如你所说,点符号只是在类属性上调用getter和setter,而不是消息,这就是你的第二个语句不正确的原因。您可能想要比较的两行是:

self.display.text = [self.display.text stringByAppendingFormat:digit];
[[self display] setText:[[[self display] text] stringByAppendingFormat:digit]];

请注意,必须以正常方式调用消息stringByAppendingFormat。 点符号只是写得更快而没有那么多括号,但是一旦编译就会执行完全相同的指令。

答案 3 :(得分:2)

当您的代码被编译时,clang实际上首先采用所有的点符号并将其转换为方法/括号表示法,因此self.display[self display]完全相同。从Objective-C 2.0开始,Dot符号实际上是相当新的。这只是为了方便。

点符号只能用于属性,因为做你想做的事情(不会编译)会变得很麻烦:

self.display.text.stringByAppendingFormat:digit;

它也不适用于带有多个参数的方法,因为你需要在参数之间放置空格,突然代码行看起来很笨拙而难以阅读。

答案 4 :(得分:2)

使用选择器表示法而不是点表示法的另一个原因是由于Objective C中的动态语言功能。例如,请考虑以下内容:

NSString *s = @"Hello World!";
NSLog(@"Length is %d", s.length);

这正如我们所期望的那样。但是,Objective C中的对象可以使用类型id传递。请考虑以下事项:

id s = @"Hello World!";
NSLog(@"Length is %d", s.length);

这不会编译,因为id没有名为length的属性。但是,以下内容可行:

id s = @"Hello World!";
NSLog(@"Length is %d", [s length]);

这有效的原因是Objective C知道NSString,因此知道有一些对象类型响应选择器length。当然,如果你尝试以下方法:

id s = [[UIView alloc] init];
NSLog(@"Length is %d", [s length]);

您的代码将正确编译,但由于unrecognized selector sent to instance没有UIView选择器,因此会发生运行时异常(length)。

答案 5 :(得分:2)

我们假设我们的班级Class包含变量variableOne,我们将使用这两种符号。

点符号是访问变量的最纯粹方式。这也是括号表示最有可能在幕后进行的方式。输入Class.variableOne ... variableOneClass和&#34;的一部分。&#34;在类告诉编译器它想要访问类的一部分 - 变量或方法之后。

括号表示法是使用方法来访问变量。让我们说......

-(int) setVariable:x {
    self.variableOne = x;
}

-(int) showVariable {
    return self.variableOne
}

因此,当您使用括号表示法设置变量[variableOne setVariable:5]或显示变量[variableOne showVariable]时,它会调用相应的方法。

这是一种考虑差异的非常简单的方法,我意识到另一个答案已被接受,但也许这个答案会解释为那些不理解另一个答案的人。 < / p>