可以说我有一个简单的类,如下所示:
@interface A {
// @public
int var;
}
// @property(some_property) int var;
@end
当我想访问变量var时,我有一些选择。如果我将var公开,则可以执行以下操作:
A objectA = [ [ A alloc ] init ];
NSLog( @"%d", objectA->var );
objectA->var = someNumber;
如果改为将其设置为属性,则必须执行以下操作:
A objectA = [ [ A alloc ] init ];
NSLog( @"%d", objectA.var ); // dot-syntax
NSLog( @"%d", [ objectA var ] ); // get-syntax
[ objectA setVar: someNumber ];
我都尝试过,并且它们都可以正常工作,但是我的问题是,使用旧式指针表示法访问对象内部的变量有多危险?以后我是否需要担心通过标准化方法访问现在应该处理的事情?还是我可以随心所欲地做到这一点,只要它能起作用就行吗?
最佳答案
自从几天前我对另一个问题的评论开始类似的讨论以来,我将投入自己的2美分。
您应该始终使用访问器方法在该对象的类的实现之外设置和获取该对象的属性。您几乎应该始终使用访问器方法来访问类的属性,即使在所述类的实现内部也是如此。
以下列出了一些原因:
[self setNeedsDisplay]
。如果不调用setter,而是直接设置ivar,则将完全绕开此行为。再次,您可能会认为很好,只要您知道 setter 不需要执行此类操作即可,但是需求会发生变化,并且通过从一开始就使用 setter ,您可以更轻松地进行线下更改。 objectA->var
示例,它更适用于类的自身实现(var = ...
)中的直接ivar访问,其中self->
由编译器隐含/插入。问题是,尤其是在长方法中,您可能会看到一个赋值语句,而一眼不知道所赋值的变量是否在当前作用域或实例变量本地。可以通过使用诸如下划线,Hungarian notation等为ivars前缀等命名约定来缓解这种情况,但是,Objective-C约定仍然意味着最好使用self.var = ...
或[self setVar:...]
(顺便说一句,它们在语义上是完全相同的)。 请记住,关于在类的实现中使用直接ivar访问,我使用了“几乎”限定符。如果实现自定义访问器方法(而不是@synthesizing属性),则必须直接在访问器的实现内部访问ivar。另外,有些人不同意,但是直接在类的初始值设定项(
-init
)方法中设置ivars是一个好主意(也是Apple的建议)。这样做的原因是,当一个类没有完全初始化时,您可能希望避免setter的副作用。例如,您不希望KVO观察者在发现通知对象处于不一致/部分初始化状态时收到更改通知。关于objective-c - 在Objective-C中使用指针式分配与 setter 方法有多危险?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14903920/