我正在深入研究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;
}
感谢。
答案 0 :(得分:12)
您正在使用新语法使用旧语法的有趣时间进入Objective-C开发。点语法是语法糖,在某些情况下你可以使用它,但你不应该。
以下是无效的语法。你使用冒号的任何东西(除了镶嵌者或吸气剂),你都不会使用点符号。
self.display.text = self.display.text.stringByAppendingFormat:digit;
另外,您可以使用stringByAppendingString
,而不是stringByAppendingFormat
您使用点符号来访问变量,而不是调用会产生影响的操作。
<强>正确:强>
self.foo.attributeOfMyClass
<强>不正确:强>
self.foo.downloadSomethingFromAWebsite
确保总是使用点符号来访问属性值,并且总是使用括号表示法(即使你不必须)来调用操作方法,代码一目了然会更加清晰。
答案 1 :(得分:5)
点符号只是一种特定方法的简写 - 即访问者。您可以在以下情况下使用它:
foo.bar = 3;
相当于[foo setBar:3];
。foo.bar
相当于[foo bar]
。点符号只是 的简写 - 它与属性的关系没有任何魔力。您可以理论上使用点符号发送任何不带参数的消息(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
... variableOne
是Class
和&#34;的一部分。&#34;在类告诉编译器它想要访问类的一部分 - 变量或方法之后。
括号表示法是使用方法来访问变量。让我们说......
-(int) setVariable:x {
self.variableOne = x;
}
-(int) showVariable {
return self.variableOne
}
因此,当您使用括号表示法设置变量[variableOne setVariable:5]
或显示变量[variableOne showVariable]
时,它会调用相应的方法。
这是一种考虑差异的非常简单的方法,我意识到另一个答案已被接受,但也许这个答案会解释为那些不理解另一个答案的人。 < / p>