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实际上与访问器相同。财产如何申报并不重要。