因此,在我看到的一些代码中,他们直接访问对象ivar,而不是使用访问器。使用它们而不是访问器的优点是什么?如何直接访问ivars与使用访问器不同?
那么怎么会变成这样
thing = object->ivar
与此不同?
thing = object.ivar
谢谢。
因此,在我看到的一些代码中,他们直接访问对象ivar,而不是使用访问器。使用它们而不是访问器的优点是什么?如何直接访问ivars与使用访问器不同?
那么怎么会变成这样
thing = object->ivar
与此不同?
thing = object.ivar
谢谢。
首先让我说,我完全不喜欢Objective-C点符号。它为了简洁而牺牲可理解性,这是一件坏事。事实上,这里的另外两个答案都显示了点符号引入的混淆类型的证据。
饶有兴趣地讨论了一下,我现在试着回答这个问题。
在引擎盖下,Objective-C对象实现为指向C结构的指针。这就是为什么
obj->ivar
有时有效。鉴于这是一个C结构
(* OBJ).ivar
也应使用外上述工作完全按照自己说了这么多,你可以让高德私人或受保护的期待下,在这种情况下,它们可见的范围将导致编译器错误。
当应用于Objective-C对象(这是一个不会忘记的指针)时,点运算符的含义完全不同。这句法糖用于发送访问消息的对象意思是:
foo = obj.property;
obj.property = foo;
生效相同到
foo = [obj property];
[obj setProperty: foo];
这是所有有给点记号。如果通过代码将第一种形式的所有实例更改为第二种形式的实例,那么编译器所做的每件事都会用点符号表示。
特别
@property
使用点符号。你可以声明这个集合,并以传统的方式获得访问器作为Objective C方法,尽管对于逻辑属性的东西使用@property
声明绝对是最好的做法。鉴于上述情况,obj->ivar
和obj.ivar
之间的主要差别是,前者直接修改的ivar和后者调用的存取,这意味着后者可以做需要(任何存储器管理东西保留,版本,复印等),也可以调用键值观察。
这是c/C++和objective-c之间巨大差异的一件事情。
在C/C++中,.
直接访问变量,->
访问变量,如果它是变量的指针,基本上它是相同的。
在Objective-C中,.
是使用setter和getter函数访问属性的快捷方式,它总是使用这些函数总是。如果没有该名称的财产,则无法使用它访问ivars。
有人说,允许直接访问变量是“脏”的。如果更多人在代码上工作,使用访问器会更“干净”,因为在变量变化的地方进行调试可能更容易,因为您始终可以在setter中中断。
你甚至可以做“坏”的东西吧,比如:
NSArray *array = [NSArray alloc] init];
int count = array.count;
array.release;
这将在技术上的工作,因为array.release
是[array release]
一个快捷方式,但它是坏的风格来使用.
其他的东西,然后属性。
所有ivars都是私人的。无法直接从对象外部访问它们。因此,您的两个代码示例都是相同的,采用ObjC术语。
当您拨打object.ivar
时,您真正在做的是拨打object
的ivar
选择器。这可能是你自己写的一个getter方法,或者更可能是你用@synthesize
创建的一个合成的getter方法。
thing
然而,是伊娃。您的代码将调用ivar
选择器object
并将结果直接分配给您的实例的thing
伊娃。
如果您将其写为self.thing = object.ivar
,那么您将使用实例的setter方法将其分配给thing
。
在ObjC中使用访问器(特别是综合属性)的一些优点是符合KVO/KVC;更好的并发支持;访问控制(只读,读写);以及访问者以任何其他OO语言提供的所有优点。
将近-1:ivars不必是私人的(请参阅'@ public'和'@ protected')。 – JeremyP
性能的优点是它们调用与高德的工作方法,以代替直接调用实例变量的,所以你可以做这样的事情:
-(void)setFrame:(CGRect)frame
{
if([self frameIsValid:frame])
{
if(self.flipsFrames)
{
frame.size = CGSizeMake(frame.size.height,frame.size.width);
}
[super setFrame:frame];
[delegate viewSubclass:self ChangedFrameTo:frame];
}
}
这里所示的四个优势:
另一个优点:
-(NSInteger) amountOfMinutes
{
return amountOfSeconds * 60;
}
可以使用1周的ivar为多个属性,节约存储器并防止/减少冗余度,同时保持有用不同的格式。
使用ivars没有什么优势,除非你不想使用属性,所以你的类更加封装。这并不是不可能达到,但它表明它不应该达到。
-1:这个答案有很多错误。最糟糕的是,点符号与属性无关。只要存在访问者,就可以使用它。另外,由于什么时候数组的元素数不是数组的属性? – JeremyP
count不是数组的属性,也许你应该在downvoting之前检查它?属性是一个Objective-C 2.0特性,所以它只是一个函数。如果你不相信你可以检查NSArray.h。另外请查看http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml?showone=Properties#Properties – Bastian
@Bastian这是意想不到的,但随着后来的属性介绍它是有道理的。 count是一个令人困惑的例子,但你添加的版本更清晰。无论如何,我会删除我的第一条评论,但我会让downvote保持不变,直到“据我所知不能将所有内容放在属性中......”被移除或证明。据我所知,通过正确使用保留和分配,每种类型都可以成为一个属性。至少结构可以是属性(例如UIView的框架,由CGPoint结构和CGSize结构组成的CGRect结构)。 – Aberrant