Objective-C中用于非结构化的点对箭头表示法



我看到了用于结构的箭头表示法的例子。在一个教程中,我在视图控制器实现文件中看到了以下语法:

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";

该代码调用myInputFieldgetter方法。这样做可能有充分的理由,所以通常是最安全的。

self->_myInputField.text = @"text field test";

该代码直接访问_myInputField实例变量

在这种情况下,myInputFieldgetter方法访问_myInputField实例变量,这就是为什么这两个调用似乎做了相同的事情。但这只是一个实施细节;getter方法完全有可能访问不同名称的实例变量,执行其他操作(副作用),或者根本不访问实例变量。

最新更新