关于ios:在Objective c中使用下划线作为实例变量

Using underscore for instance variables in Objective c

我在阅读关于在目标C中的实例变量前面加前缀的文章,特别是下面的文章,

在目标C中用下划线前缀属性名

cocoa objective-c类中变量前面的下划线是如何工作的?

正如我所理解的,当我们使用下划线时,我们直接访问ivar,而不是使用访问器。这将如何影响应声明为"copy"而不是"strong"的属性。尤其是对于街区。

我使用这个公约会遇到麻烦吗?


如nhgrif所说,您应该使用访问器(在大多数情况下)。在实例变量的开头添加下划线的原因是,这样做可以确保对实例变量的任何访问都在源代码中脱颖而出。例如,如果一个方法中有这三行:

1
2
3
self.myInstance = 0;
myInstance = 0;
_myInstance = 0;

self.myinstance=0由于"self"而清除:您正在调用属性setter。_ myInstance=0也很明显,因为下划线:您正直接分配给实例变量。这是好是坏取决于环境,但是阅读这段代码我知道你在做什么,我知道这是故意的。

如果实例变量没有以下划线开头,则可以编写myinstance=0。我可能怀疑它是直接分配给实例变量的,但是只有在仔细阅读了代码之后。您可能在某个地方有一个名为myinstance的全局变量。或者方法中的一个参数或局部变量(StackOverflow中有很多问题,因为这个代码不能工作;有人想要设置一个属性,但是改变了一个局部变量),或者你可能打算使用访问器,但是忘记了"self"。并且认为这是可以的,因为它可以编译。

因此,"下划线"约定向每个人清楚地说明了您的代码是做什么的,以及您打算做什么。所以您应该使用下划线,但很少使用实例变量。

如果您使用的是ARC,那么如果直接使用实例变量,引用计数将正常工作,但是"复制"语义将不起作用。因此,将一个块直接分配给一个实例变量是一个非常糟糕的主意(除非您手工复制它)。如果没有ARC,您还必须手工进行参考计数(保留/释放)。最重要的是,您可以观察一个属性(如果有人更改了一个属性,则会自动调用代码),如果直接访问实例变量,则根本不起作用。


您要使用实例变量的一个地方是,如果您重写了任何setter方法,即:

1
2
3
- (void)setFoo:(MyFooInstance *)fooInstance{
    _foo = fooInstance;
}

否则你将创建一个整洁的无限循环…


当您使用下划线作为变量名的一部分时,您将访问一个名称中包含下划线的变量——这(几乎)很简单。除此之外,还有命名变量的约定,并且这些约定(取决于谁)有时包括与带有前导下划线的属性对应的命名实例变量。

但是下划线没有什么神奇之处——它本身并没有调用任何特殊的功能。只有约定(在给定的代码中可能存在也可能不存在)才导致下划线具有任何额外的意义。


您应该使用在声明属性时创建的访问器。如果您不需要访问器,那么您不应该创建一个属性,而应该只创建一个IVAR。

也就是说,假设您没有编写自定义访问器,那么直接访问ivar实际上与访问器相同。财产如何申报并不重要。