Objective-C命名规范 - 一次澄清

3

我有一个疑问,对我来说并不明显。

假设我们在一个类中有一个名为myProperty@property。在合成它时,我们可以有两种选择。一种是将一个名为_someIVarivar分配给它,或者我们可以仅仅省略它,在这种情况下编译器会帮我们创建一个同名的ivar,即myProperty。在第一种情况下,我们可以使用ivar_someIVar访问该属性。在第二种情况下,我们可以使用由编译器为我们创建的ivarmyProperty

现在我的疑问是,在从已经在导航堆栈中的视图控制器推送另一个视图控制器时,我们使用以下代码:

[self.navigationController pushViewController:newViewController animated:YES];

作为一个属性,我认为navigationController应该有个ivar与之对应。只有两种可能: 1)苹果公司的约定是使用下划线(_)作为变量名前缀。如果是这样的话,我可以这样调用pushViewController:animated:方法:
[_navigationController pushViewController:newViewController animated:YES];

第二种可能性显然是没有下划线的ivar。

[navigationController pushViewController:newViewController animated:YES];

但是编译器不允许我以任何方式访问navigationController。为什么?这与私有属性相关还是我根本不理解Objective-C?


1
为什么你想要这样做呢?不要试图破坏封装性。实例变量是私有的,有很好的理由。它们是实现细节,可能随时会发生变化。 - Matthias Bauch
3个回答

3

您不知道苹果是如何实现navigationController属性的,因此您不能假设UIViewController类中有一个浮动的_navigationController ivar。事实上:属性可以声明为@dynamic,在这种情况下,实现可以是任何东西。

仅凭属性本身无法猜测支持属性的ivar。


2
我们没有UIKit的源代码,因此无法确定该ivar的名称。
但是,按照苹果的惯例,似乎是_ivar。
看起来,苹果使用@private声明_navigationController(或其他可能被称为的变量)为私有ivar,这意味着只有该类的实例而不是子类才能访问该ivar。
此外,该属性被声明为只读,因此您甚至不能尝试写入它,这意味着苹果确实不希望您更改它。
请注意,ivar名称有两个以上的可能性。属性可以由任何名称的ivar表示。如果您查看苹果的文档,它们有一个示例:
@synthesize firstName, lastName, age=yearsOld;

这表示应该合成firstName、lastName和age的访问器方法,并且属性age由实例变量yearsOld表示。

2

您不能猜测ivar的名称。而且,您不应该尝试访问在超类中声明的ivar。第三点是,无法保证navigationController属性由ivar支持,它也可能由自定义getter支持计算其值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接