2011-10-31 30 views

回答

2

首先让我说,我完全不喜欢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声明绝对是最好的做法。
  • 你不需要支持实例变量。没有理由为什么你的getter和setter不能计算值。

鉴于上述情况,obj->ivarobj.ivar之间的主要差别是,前者直接修改的ivar和后者调用的存取,这意味着后者可以做需要(任何存储器管理东西保留,版本,复印等),也可以调用键值观察。

2

这是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]一个快捷方式,但它是坏的风格来使用.其他的东西,然后属性。

+2

-1:这个答案有很多错误。最糟糕的是,点符号与属性无关。只要存在访问者,就可以使用它。另外,由于什么时候数组的元素数不是数组的属性? – JeremyP

+0

count不是数组的属性,也许你应该在downvoting之前检查它?属性是一个Objective-C 2.0特性,所以它只是一个函数。如果你不相信你可以检查NSArray.h。另外请查看http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml?showone=Properties#Properties – Bastian

+0

@Bastian这是意想不到的,但随着后来的属性介绍它是有道理的。 count是一个令人困惑的例子,但你添加的版本更清晰。无论如何,我会删除我的第一条评论,但我会让downvote保持不变,直到“据我所知不能将所有内容放在属性中......”被移除或证明。据我所知,通过正确使用保留和分配,每种类型都可以成为一个属性。至少结构可以是属性(例如UIView的框架,由CGPoint结构和CGSize结构组成的CGRect结构)。 – Aberrant

-1

所有ivars都是私人的。无法直接从对象外部访问它们。因此,您的两个代码示例都是相同的,采用ObjC术语。

当您拨打object.ivar时,您真正在做的是拨打objectivar选择器。这可能是你自己写的一个getter方法,或者更可能是你用@synthesize创建的一个合成的getter方法。

thing然而,伊娃。您的代码将调用ivar选择器object并将结果直接分配给您的实例的thing伊娃。

如果您将其写为self.thing = object.ivar,那么您将使用实例的setter方法将其分配给thing

在ObjC中使用访问器(特别是综合属性)的一些优点是符合KVO/KVC;更好的并发支持;访问控制(只读,读写);以及访问者以任何其他OO语言提供的所有优点。

+0

将近-1:ivars不必是私人的(请参阅'@ public'和'@ protected')。 – JeremyP

0

性能的优点是它们调用与高德的工作方法,以代替直接调用实例变量的,所以你可以做这样的事情:

-(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没有什么优势,除非你不想使用属性,所以你的类更加封装。这并不是不可能达到,但它表明它不应该达到。