實(shí)例變量(instance variable):由類定義的成員變量,OC中一般聲明在{ }內(nèi)。
屬性(property):編譯器自動將變量的set和get方法的合成,代碼中使用@property,可用點(diǎn)語法讀取,可作為變量使用,可與外界接觸。
關(guān)聯(lián)變量(Associated Object):使用objc_setAssociatedObject運(yùn)行時(shí)創(chuàng)建的關(guān)聯(lián)對象,屬于類的成員變量,但是不是屬性。
成員變量(Member variable):類成員變量包含實(shí)例變量、屬性和關(guān)聯(lián)變量。
關(guān)于實(shí)例變量和屬性,我們看下面這個(gè)類
@interface ViewController : UIViewController
{
int intV;
NSString *_aaa;
UIView *_testView;
}
@property (nonatomic, copy) NSString *bbb;
@property (nonatomic, copy) NSString *aaa;
@end
這里我用運(yùn)行時(shí)獲取實(shí)例:
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)建帶下劃線的實(shí)例變量:如_bbb。
- 2.一般情況下,每個(gè)屬性變量都對應(yīng)一個(gè)實(shí)例變量,反之就不一定了。
如果在.m文件中加入以下代碼:
@implementation ViewController
@synthesize bbb=_aaa;
...
@end
屬性bbb會關(guān)聯(lián)上實(shí)例變量_aaa,導(dǎo)致系統(tǒng)不會自動創(chuàng)建_bbb,這時(shí)候用class_copyIvarList運(yùn)行時(shí)獲取實(shí)例數(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)行時(shí),給self關(guān)聯(lián)了一個(gè)numPro變量,用法與屬性一樣,但是不提供實(shí)例變量(即不能使用_numPro),使用運(yùn)行時(shí)class_copyIvarList、class_copyPropertyList都無法獲取到該對象。