2011-10-31 33 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沒有什麼優勢,除非你不想使用屬性,所以你的類更加封裝。這並不是不可能達到,但它表明它不應該達到。