点符号与方法符号

我正在潜心研究iOS编程,我很难理解Dot Notation和Method Notation。

据我所知,Dot Notation可以用来在属性上调用setter / getters,并且更易于读/写。 方法表示法用于发送消息到对象来操纵它们等

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

- (IBAction)digitPressed:(UIButton *)sender { NSString *digit = [sender currentTitle]; self.display.text = [self.display.text stringByAppendingFormat:digit]; self.display.text = self.display.text.stringByAppendingFormat:digit; } 

谢谢。

你正在一个有趣的时间进入到Objective-C的开发中,在这个时候,新的语法正在使用旧的语法。 点语法是语法糖,有些情况下你可以使用它,但你不应该这样做。

以下是无效的语法。 任何你使用冒号的地方(除了setters或getters),你都不会使用点符号。

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

此外,你会使用stringByAppendingString ,而不是stringByAppendingFormat

您使用点符号来访问variables,而不是调用将有影响的动作。

正确: self.foo.attributeOfMyClass

不正确: self.foo.downloadSomethingFromAWebsite

确保您始终使用点符号来访问属性值,并且始终使用括号表示法(即使不需要)来调用操作方法,但您的代码一眼就会清晰得多。

点符号只是一种特定types的方法 – 即访问器。 您可以在以下情况下使用它:

  1. 设置属性时: foo.bar = 3; 相当于[foo setBar:3];
  2. 当请求一个属性时:除了上面的情况之外, foo.bar等同于[foo bar]

点符号只是简写 – 关于它与属性的关系没有任何魔力。 理论上你可以使用点符号来发送任何不带参数的消息( foo.doSomething ),但是这会是非常糟糕的样式 ,因为点符号是用于属性的。 另外请注意,如果在学习的时候点符号与方括号混淆,那么完全避免点符号是一个完美的select。 如果你喜欢,这只是一个你可能用来访问的快捷方式。

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

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

请注意,消息stringByAppendingFormat必须被称为正常的方式。 点符号只是写得更快,没有那么多的括号,但是一旦编译完成,它将执行完全相同的指令。

使用select符表示法而不是点表示法的另一个原因是由于Objective C中的dynamic语言function。作为示例,请考虑以下几点:

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

这符合我们的预期。 但是,Objective C中的对象可能会使用idtypes来传递。 考虑以下:

 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 ,所以知道有一些对象types响应select器的length 。 当然,如果您尝试以下操作:

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

您的代码将正确编译,但会发生运行时exception( unrecognized selector sent to instance ),因为UIView没有lengthselect器。

假设我们有variablesvariableOne Class ,我们将使用这两个记号。

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

括号表示法是使用一种方法来访问variables。 比方说…

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

所以,当你使用方括号来设置variables[variableOne setVariable:5]或显示variables[variableOne showVariable]它会调用相应的方法。

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

当你的代码被编译时,clang实际上首先把你所有的点符号转换成方法/括号符号,所以self.display[self display]是完全一样的。 在Objective-C 2.0中,点符号实际上是相当新的。 这只是为了方便。

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

self.display.text.stringByAppendingFormat:digit;

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