When using Objective-C properties can you stop creating instance variables altogether or do explicit instance variables (not the ones synthesized by the properties) still serve a purpose where properties would be inappropriate?
在使用Objective-C属性时,是否可以完全停止创建实例变量,或者执行显式实例变量(不是由属性合成的变量)仍然可以达到不合适的目的?
4 个解决方案
#1
13
can you stop creating instance variables altogether
是否可以完全停止创建实例变量
No, you can't (in a sense). What you can do is stop declaring them if you have properties. If you synthesize a property and you haven't declared the instvar, it will get declared for you, so you are creating an instance variable, just not explicitly.
不,你不能(在某种意义上)。如果你有属性,你可以停止声明它们。如果您合成了一个属性,而您还没有声明instvar,那么它将为您声明,因此您正在创建一个实例变量,只是没有显式地声明。
do they still serve a purpose where properties would be inappropriate?
它们是否仍然适用于不合适的属性?
It used to be the advice to create properties for everything because having synthesized properties does almost all of the retains and releases for you. However, with ARC that reason for using properties to wrap the memory management has gone away. The advice now (for ARC) is, I believe, use properties to declare your external interface, but use direct instance variables where the variable is part of the object's internal state.
它曾经是为所有事物创建属性的建议,因为合成属性几乎可以为您完成所有的保留和发布。但是,由于使用了ARC的原因,使用属性来包装内存管理已经消失了。现在(对于ARC)的建议是,我相信,使用属性来声明外部接口,但是使用直接的实例变量,其中变量是对象的内部状态的一部分。
That's a good reason to adopt ARC: properties revert to their true purpose only of being part of the class's API and it's no longer necessary to use them as a hacky way to hide memory management work.
这是采用ARC的一个很好的理由:属性恢复到它们的真正目的,只是作为类的API的一部分,不再需要使用它们作为隐藏内存管理工作的一种陈腐方式。
Edit
编辑
One more thing: you can now declare instance variables in the @implementation
so there is now no need to leak any implementation details in the @interface
. i.e.
还有一件事:您现在可以在@implementation中声明实例变量,因此现在不需要在@interface中泄漏任何实现细节。即。
@implementation MyClass
{
NSString* myString;
}
// method definitions
@end
And I'm pretty sure it works in categories too. - see comment below
我很确定它也适用于分类。——请参见下面的评论
#2
9
I recommend declaring everything as properties and avoiding manual ivars altogether. There is no real upside to manually creating ivars. Declare public properties in your header @interface
, declare private properties in a private class extension in your .m file.
我建议将所有内容都声明为属性,并避免使用手工ivars。手工创建ivars并没有真正的好处。在header @interface中声明公共属性,在.m文件中的私有类扩展中声明私有属性。
To some of JeremyP's points, internal use of accessors still has significant value under ARC, even though memory management is no longer a significant concern. It ensures that KVO works properly, subclasses better, supports custom setters (particularly for things like NSTimer
), supports custom getters (such as for lazy instantiation), etc. It is exceedingly error-prone to have a mix of accessors and ivars. It's far too easy to forget which you need to access in which way. Consistency is the hallmark of good ObjC.
对于JeremyP的某些观点来说,在ARC下内部访问仍然有重要的价值,即使内存管理不再是一个重要的关注点。它确保KVO工作正常,子类更好,支持自定义setter(特别是对于像NSTimer这样的东西),支持自定义getter(比如惰性实例化)等等。很容易忘记以何种方式访问哪些内容。一致性是好的目标的标志。
If you absolutely must declare an ivar for some reason, then you should do it in the @implementation
block as JeremyP notes.
如果由于某种原因您必须声明一个ivar,那么您应该在@implementation块中这样做,JeremyP注意到。
UPDATE (Oct-2013):
更新(10 - 2013):
Apple's guidance (From Programming with Objective-C: Encapsulating Data):
苹果的指导(来自Objective-C:数据封装):
Most Properties Are Backed by Instance Variables
大多数属性都由实例变量支持
In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use
self
:一般来说,您应该使用访问器方法或点语法进行属性访问,即使您是从对象的实现中访问对象的属性,在这种情况下,您应该使用self:
...
…
The exception to this rule is when writing initialization, deallocation or custom accessor methods, as described later in this section.
此规则的例外是在编写初始化、释放或自定义访问器方法时,如本节后面所述。
#3
0
This question was addressed before here
这个问题之前已经讨论过了
When you use synthesize
the instance variables are handled and instantiated for you. If you're using Lion with the new version of XCode also take a look at the various properties in ARC in Transitioning to ARC
当您使用synthesize时,实例变量将被处理并为您实例化。如果您使用的是Lion,新版本的XCode还会查看转换到ARC的各种属性。
#4
0
you can always access properties from outside. So if you want a variable only to be read from inside a class you still have to declare a iVar. Also accessing a public ivar with object->ivar
is slightly faster than using a method-call.
您总是可以从外部访问属性。如果你想要一个变量只在类中读取,你仍然需要声明一个iVar。使用object->ivar访问公共ivar比使用方法调用要稍微快一些。
#1
13
can you stop creating instance variables altogether
是否可以完全停止创建实例变量
No, you can't (in a sense). What you can do is stop declaring them if you have properties. If you synthesize a property and you haven't declared the instvar, it will get declared for you, so you are creating an instance variable, just not explicitly.
不,你不能(在某种意义上)。如果你有属性,你可以停止声明它们。如果您合成了一个属性,而您还没有声明instvar,那么它将为您声明,因此您正在创建一个实例变量,只是没有显式地声明。
do they still serve a purpose where properties would be inappropriate?
它们是否仍然适用于不合适的属性?
It used to be the advice to create properties for everything because having synthesized properties does almost all of the retains and releases for you. However, with ARC that reason for using properties to wrap the memory management has gone away. The advice now (for ARC) is, I believe, use properties to declare your external interface, but use direct instance variables where the variable is part of the object's internal state.
它曾经是为所有事物创建属性的建议,因为合成属性几乎可以为您完成所有的保留和发布。但是,由于使用了ARC的原因,使用属性来包装内存管理已经消失了。现在(对于ARC)的建议是,我相信,使用属性来声明外部接口,但是使用直接的实例变量,其中变量是对象的内部状态的一部分。
That's a good reason to adopt ARC: properties revert to their true purpose only of being part of the class's API and it's no longer necessary to use them as a hacky way to hide memory management work.
这是采用ARC的一个很好的理由:属性恢复到它们的真正目的,只是作为类的API的一部分,不再需要使用它们作为隐藏内存管理工作的一种陈腐方式。
Edit
编辑
One more thing: you can now declare instance variables in the @implementation
so there is now no need to leak any implementation details in the @interface
. i.e.
还有一件事:您现在可以在@implementation中声明实例变量,因此现在不需要在@interface中泄漏任何实现细节。即。
@implementation MyClass
{
NSString* myString;
}
// method definitions
@end
And I'm pretty sure it works in categories too. - see comment below
我很确定它也适用于分类。——请参见下面的评论
#2
9
I recommend declaring everything as properties and avoiding manual ivars altogether. There is no real upside to manually creating ivars. Declare public properties in your header @interface
, declare private properties in a private class extension in your .m file.
我建议将所有内容都声明为属性,并避免使用手工ivars。手工创建ivars并没有真正的好处。在header @interface中声明公共属性,在.m文件中的私有类扩展中声明私有属性。
To some of JeremyP's points, internal use of accessors still has significant value under ARC, even though memory management is no longer a significant concern. It ensures that KVO works properly, subclasses better, supports custom setters (particularly for things like NSTimer
), supports custom getters (such as for lazy instantiation), etc. It is exceedingly error-prone to have a mix of accessors and ivars. It's far too easy to forget which you need to access in which way. Consistency is the hallmark of good ObjC.
对于JeremyP的某些观点来说,在ARC下内部访问仍然有重要的价值,即使内存管理不再是一个重要的关注点。它确保KVO工作正常,子类更好,支持自定义setter(特别是对于像NSTimer这样的东西),支持自定义getter(比如惰性实例化)等等。很容易忘记以何种方式访问哪些内容。一致性是好的目标的标志。
If you absolutely must declare an ivar for some reason, then you should do it in the @implementation
block as JeremyP notes.
如果由于某种原因您必须声明一个ivar,那么您应该在@implementation块中这样做,JeremyP注意到。
UPDATE (Oct-2013):
更新(10 - 2013):
Apple's guidance (From Programming with Objective-C: Encapsulating Data):
苹果的指导(来自Objective-C:数据封装):
Most Properties Are Backed by Instance Variables
大多数属性都由实例变量支持
In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use
self
:一般来说,您应该使用访问器方法或点语法进行属性访问,即使您是从对象的实现中访问对象的属性,在这种情况下,您应该使用self:
...
…
The exception to this rule is when writing initialization, deallocation or custom accessor methods, as described later in this section.
此规则的例外是在编写初始化、释放或自定义访问器方法时,如本节后面所述。
#3
0
This question was addressed before here
这个问题之前已经讨论过了
When you use synthesize
the instance variables are handled and instantiated for you. If you're using Lion with the new version of XCode also take a look at the various properties in ARC in Transitioning to ARC
当您使用synthesize时,实例变量将被处理并为您实例化。如果您使用的是Lion,新版本的XCode还会查看转换到ARC的各种属性。
#4
0
you can always access properties from outside. So if you want a variable only to be read from inside a class you still have to declare a iVar. Also accessing a public ivar with object->ivar
is slightly faster than using a method-call.
您总是可以从外部访问属性。如果你想要一个变量只在类中读取,你仍然需要声明一个iVar。使用object->ivar访问公共ivar比使用方法调用要稍微快一些。