實例變量(instance variable):由類定義的成員變量,OC中一般聲明在{ }內(nèi)。
屬性(property):編譯器自動將變量的set和get方法的合成,代碼中使用@property,可用點語法讀取,可作為變量使用,可與外界接觸。
關(guān)聯(lián)變量(Associated Object):使用objc_setAssociatedObject運(yùn)行時創(chuàng)建的關(guān)聯(lián)對象,屬于類的成員變量,但是不是屬性。
成員變量(Member variable):類成員變量包含實例變量、屬性和關(guān)聯(lián)變量。
關(guān)于實例變量和屬性,我們看下面這個類
@interface ViewController : UIViewController
{
int intV;
NSString *_aaa;
UIView *_testView;
}
@property (nonatomic, copy) NSString *bbb;
@property (nonatomic, copy) NSString *aaa;
@end
這里我用運(yùn)行時獲取實例:
unsigned int varNumbers;
Ivar *vars = class_copyIvarList(self.class, &varNumbers);
這里varNumbers數(shù)值為4,輸出IvarName是:intV、_aaa、_testView、_bbb,
unsigned int proNumbers;
objc_property_t *propertys = class_copyPropertyList(self.class, &proNumbers);
獲取屬性數(shù)量為2,分別是aaa和bbb。
這里就發(fā)現(xiàn):
- 1.屬性@property修飾的變量會自動創(chuàng)建帶下劃線的實例變量:如_bbb。
- 2.一般情況下,每個屬性變量都對應(yīng)一個實例變量,反之就不一定了。
如果在.m文件中加入以下代碼:
@implementation ViewController
@synthesize bbb=_aaa;
...
@end
屬性bbb會關(guān)聯(lián)上實例變量_aaa,導(dǎo)致系統(tǒng)不會自動創(chuàng)建_bbb,這時候用class_copyIvarList運(yùn)行時獲取實例數(shù)量就是3,輸出IvarName是:intV、_aaa、_testView。而屬性變量還是aaa和bbb。
關(guān)聯(lián)變量:
- (void)setNumPro:(int)numPro
{
objc_setAssociatedObject(self, @selector(numPro), @(numPro), OBJC_ASSOCIATION_ASSIGN);
}
- (int)numPro
{
return [objc_getAssociatedObject(self, _cmd) intValue];
}
這里通過運(yùn)行時,給self關(guān)聯(lián)了一個numPro變量,用法與屬性一樣,但是不提供實例變量(即不能使用_numPro),使用運(yùn)行時class_copyIvarList、class_copyPropertyList都無法獲取到該對象。