Class A:
[cpp]
@interface ClassA : NSObject{
}
@property(nonatomic, retain) Foo* foo;
@end
Class B:
[cpp]
@interface ClassB : NSObject{
Foo* foo;
}
@property(nonatomic, retain) Foo* foo;
@end
上面兩個類的不同是:第二個類包含一個名字為"foo"的 ivar。
如果在類的實現部分包含了"@synthesize foo;",
並且用了比較新的編譯器(好像是從 4.2 開始的),
對於第一個類,編譯器會自動為類添加一個合適的ivar,
你可以直接用foo,就像定義了foo這個成員變量一樣。www.2cto.com
ivar 的 synthesis 機制依賴於 Objective-C 的“修復脆弱基類的特性”。
在大部分編譯型語言中,ivar 的訪問是通過“對象地址 + ivar 偏移量”的方式,
子類中的 ivar 需要在基類 ivar 的後面,這樣子類必須知道基類對象的大小才可以計算出自身 ivar 的開始地址。
當改變基類的大小時,比如增加或者減少 ivar,就必須重新編譯所有子類。
Objective-C 解決“脆弱基類”的方式是:將所有 ivar 的大小作為一項元數據,存儲到類的元信息中,並且在運行時進行設置。
這樣可以通過“對象地址+基類大小+ivar偏移量”的方式來計算相應的ivar 地址,並訪問對應的ivar。
關於“ivar synthesis”的底層機制依賴於編譯器,總之編譯器會調整 ivar 區域,以達到動態添加 ivar 的目的。