2012-10-15 70 views
3

所以...我還是相當新的目標C ...採取一些iTunes U馬...做一些練習和所有...「財產是由伊娃支持」?這在技術上意味着什麼?

但是,當您使用@synthesize myProperty = _myIvarPropertyNameToUse; ... iOS 5將創建一個可以「回」該屬性的伊娃。

到底是怎麼回事就在這裏,只要那裏的東西坐在記憶...

(1)伊娃一個真正的變量? ...或者它是指向該對象中屬性位置的指針嗎?

(2)該屬性在堆上(作爲對象的一部分),對不對?伊娃也在堆上嗎?

我想我可能會失去一個大局...有一個由伊娃支持的財產有什麼意義?

感謝,

回答

0

只是要清楚,當你做@synthesize myProperty = _myIvarPropertyNameToUse;,你唯一的改變後盾伊娃的名字。行@synthesize myProperty;也將創建一個後援伊娃,但它將被稱爲myProperty,而不是_myIvarPropertyNameToUse ...

支持ivar是對象的一部分,所以是它在堆上。它可以用作一個真正的變量,這意味着你可以在目標代碼中獲取並設置它。

10

Objective-C對象只是一個C堆,它在堆上分配(或多或少)。當你聲明一個實例變量(ivar)時,它被定義爲該結構的偏移量。因此,如果手動宣佈一些高德這樣的(不要做這種方式了,但它說明了這一點):

@interface Foo : NSObject { 
    NSString *ivar1; 
    NSString *ivar2; 
} 

然後,當你+alloc一個新的實例(稱之爲foo),該結構將是一些標題後跟NSObject的ivars後跟ivar1的內存,然後是ivar2的內存。 ivar1將爲foo加上一些偏移量。 (這是不完全正確了,但留下來陪我,這是容易理解的舊的實現。)

由於foo是一個指向一個struct,你其實可以直接引用這個偏移指針爲foo->ivar1。它確實是一個結構。切勿這樣做,但它是合法的語法。

@implementation區塊內部,ivar1被自動翻譯爲self->ivar1。不要太擔心如何實現self,但相信它是一個指向你的結構的指針。再次,不要使用這種->語法。這是一個潛在的實現細節(並不總是可能的,見下文)。好吧,這就是伊娃是一個什麼樣的公司。在過去的時間(ObjC 1.0),這實際上就是我們所有的。你聲明你的ivars,然後你手工創建訪問器方法來設置和返回它們的值。

然後,ObjC2出現了,在某些情況下,這也給了我們一種叫做非脆弱ABI的東西。這在一定程度上改變了ivars的底層實現,所以你不能總是實際使用->。但是你不應該使用它。即便如此,假裝事情是舊的方式更簡單。更重要的是,ObjC2增加了這個名爲「屬性」的新東西。財產只是實現某些方法的承諾。所以,當你說:

@property (nonatomic, readwrite, strong) NSString *property; 

這幾乎是相同的說法如下:

- (NSString *)property; 
- (void)setProperty:(NSString *)aProperty; 

(所不同的是很少重要的。)請注意,這並沒有提供一個實現。它不創建ivars。它只是聲明瞭一些方法。

現在在ObjC1中,我們一遍又一遍地寫了相同的訪問器代碼。你有20個可寫入的Ivars,你寫了40個訪問器方法。他們幾乎完全相同。很多機會搞砸了。和很多乏味。謝天謝地Accessorizer

使用ObjC2,如果您添加了@synthesize,編譯器會免費爲您提供最常見的實現。它會自動製作一個與該財產同名的伊娃,並且寫一個吸氣劑和(如果需要的話)二傳手來讀寫伊娃。通過=_property只是改變了使用的伊娃爾的名字。我們稱之爲「支持伊娃。」

現在,在最新版本的編譯器中,你甚至不需要@synthesize。這種模式非常普遍,幾十年來一直是默認的,除非你告訴編譯器不要這樣做。它會自動合成帶有下劃線的伊娃(這是最佳做法)。

你應該知道的另一條信息是你應該總是使用訪問者訪問伊娃,甚至在對象內部。唯一的例外是initdealloc方法。在那裏你應該直接訪問伊娃(使用領先的下劃線)。

+0

Thanks Rob ... This is very helpful。 – RichWalt

+2

+1好帖子。總是喜歡對歷史的解釋。 – NJones

+0

好評,NJones ...歷史確實有助於理解當前狀態下的事物是如何/爲什麼。 – RichWalt