我看到了用于结构的箭头表示法的例子。在一个教程中,我在视图控制器实现文件中看到了以下语法:
self->webView.canGoBack) backButton.enabled = YES;
我不知道他们为什么不使用点号法。没有给出任何解释。我在一个有按钮和文本字段的简单项目中尝试过这一点。以下是我在按钮按下方法中输入的内容:
//header file
@property (strong, nonatomic) IBOutlet UITextField *myInputField;
//implementation file
self.myInputField.text = @"another test";
//self->_myInputField.text = @"text field test";
任何一行代码都可以正常工作。那么,为什么要用上面的一条线来代替另一条呢?
另外,请注意,箭头表示法会生成_myInputField.text
。下划线的意义是什么?
在Objective-C中,对象也是C结构。如果你是一个新手,这些知识会给你带来更多的麻烦,而不是帮助。但这有助于解释你所看到的。
Objective-C属性是一个有用的构造,它在对象(类结构中的一个新字段)中创建一个ivar,默认为以下划线为前缀的属性名。属性还将创建getter和setter方法,例如- (UITextFeild *)myInputField
和- (void)setMyInfputField
。
点表示法是Objective-C语法糖,它调用Objective-C setter和getter方法。->
箭头表示法是C语法,它将取消引用对象的指针并访问对象ivar的结构字段。
重要的是要理解dot语法实际上是在生成对这些方法的调用,所以不要试图覆盖这些方法,也不要无意中包含对它们自身的调用。
生成的方法(如- (UITextFeild *)myInputField
)的默认实现类似于以下
- (UITextFeild *)myInputField {
return self->_myInputField;
}
但是Objective-C还有另一个语法助手,允许您在不写出self->
的情况下访问_myInputField
。因此,以下实现是相同的。
- (UITextFeild *)myInputField {
return _myInputField;
}
使用直接ivar访问有一些很好的理由——最大的原因是实现了自定义的setter和getter、性能以及对KVO语言功能的谨慎控制。但在现代Objective-C中,除非你真的知道自己在做什么,否则应该避免。
如果您想了解更多信息,请阅读苹果关于Objective-C 的文档
self.myInputField.text = @"another test";
该代码调用myInputField
getter方法。这样做可能有充分的理由,所以通常是最安全的。
self->_myInputField.text = @"text field test";
该代码直接访问_myInputField
实例变量。
在这种情况下,myInputField
getter方法也访问_myInputField
实例变量,这就是为什么这两个调用似乎做了相同的事情。但这只是一个实施细节;getter方法完全有可能访问不同名称的实例变量,执行其他操作(副作用),或者根本不访问实例变量。