5

我正在深入研究 iOS 编程,但我很难理解点表示法和方法表示法的想法。

据我了解,点表示法可用于在属性上调用 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;

}

谢谢。

4

6 回答 6

12

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

以下是无效的语法。任何使用冒号的地方(除了 setter 或 getter),都不会使用点表示法。

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

此外,您将使用stringByAppendingString,而不是stringByAppendingFormat

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

正确的: self.foo.attributeOfMyClass

不正确: self.foo.downloadSomethingFromAWebsite

确保您始终使用点表示法来访问属性值,并且始终使用方括号表示法(即使您不必这样做来调用操作方法,您的代码一目了然。

于 2012-07-08T20:16:46.623 回答
5

Dot notation is just shorthand for a specific kind of method--namely, accessors. You may use it in the following cases:

  1. When setting a property: foo.bar = 3; is equivalent to [foo setBar:3];.
  2. When requesting a property: in any case except the one above, foo.bar is equivalent to [foo bar].

Dot notation is only shorthand--there is nothing magic about its relationship to properties. You could theoretically use dot notation to send any message that takes no arguments (foo.doSomething), but this would be very very bad style, as dot notation is intended for properties. Also note that if dot notation vs. square brackets is confusing you while you're learning, it's a perfectly valid choice to avoid dot notation altogether. It's just one shortcut you may use for accessors, if you like.

于 2012-07-08T20:22:48.783 回答
3

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

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

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

于 2012-07-08T20:11:51.357 回答
3

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

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

这正如我们所期望的那样工作。但是,Objective C 中的对象可以使用 type 传递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选择器。

于 2013-07-07T23:47:25.650 回答
3

假设我们有一个Class带有变量的类,variableOne我们将使用这两种表示法。

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

括号表示法是使用一种方法来访问变量。比方说...

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

-(int) showVariable {
    return self.variableOne
}

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

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

于 2014-02-21T06:04:13.230 回答
2

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

点表示法只能用于属性,因为做一些你试图做的事情(不会编译)会很麻烦:

self.display.text.stringByAppendingFormat:digit;

它也不适用于采用多个参数的方法,因为您需要在参数之间放置空格,并且突然之间代码行会显得笨拙且难以阅读。

于 2012-07-08T20:12:35.953 回答