2011-07-27 60 views

回答

3

這兩個之間的區別是,第二類包括名爲類foo伊娃,而先不。

如果您的實現包括@synthesize foo;並且您使用的是足夠現代的編譯器,那麼對於第一種情況,編譯器會自動爲您添加合適的ivar。您甚至可以稍後在同一個實現文件中訪問此隱式ivar,就像它在第二種情況下聲明一樣。

這個ivar綜合是由現代Objective-C的另一個特徵:脆弱的基類問題的修復成爲可能。在大多數編譯語言中,ivar是作爲「object address + ivar offset」來訪問的;子類的ivars必須在基類的ivars之後,所以子類必須知道基類的大小才能知道它自己的ivars在哪裏啓動。因此,改變基類的大小(例如通過添加或移除ivars)需要重新編譯所有的子類。 Objective-C通過在類的元數據中存儲類的ivar區域的大小並在運行時加載它來解決這個問題,並且ivar訪問沿着「對象地址+基類大小+ ivar偏移」的行。

伊瓦爾合成如何工作的最低層次的細節取決於編譯器,但歸結爲安排類的伊娃區域的編譯器足夠大以包含合成ivars的空間。

2

一個簡短而簡單的答案:如果您沒有明確定義ivars來支持您的屬性,編譯器將爲您的綜合屬性自動生成後備存儲。

有了這個,你只能使用屬性(通常是一件好事)訪問該值:

@interface MyClass : NSObject { 
} 
@property(nonatomic, retain) Foo* foo; 
@end 

self.foo = aFoo; // works 
foo = aFoo;  // Nope 
self->foo;  // Nope 

有了這個,你可以使用屬性訪問值兩者,並直接與伊娃(通常是一個壞東西直接去伊娃);

@interface MyClass : NSObject { 
    Foo* foo; 
} 
@property(nonatomic, retain) Foo* foo; 
@end 

self.foo = aFoo; // works 
foo = aFoo;  // yup 
self->foo;  // yes