实例变量(instance variable):由类定义的成员变量,OC中一般声明在{ }内。
属性(property):编译器自动将变量的set和get方法的合成,代码中使用@property,可用点语法读取,可作为变量使用,可与外界接触。
关联变量(Associated Object):使用objc_setAssociatedObject运行时创建的关联对象,属于类的成员变量,但是不是属性。
成员变量(Member variable):类成员变量包含实例变量、属性和关联变量。
关于实例变量和属性,我们看下面这个类
@interface ViewController : UIViewController
{
int intV;
NSString *_aaa;
UIView *_testView;
}
@property (nonatomic, copy) NSString *bbb;
@property (nonatomic, copy) NSString *aaa;
@end
这里我用运行时获取实例:
unsigned int varNumbers;
Ivar *vars = class_copyIvarList(self.class, &varNumbers);
这里varNumbers数值为4,输出IvarName是:intV、_aaa、_testView、_bbb,
unsigned int proNumbers;
objc_property_t *propertys = class_copyPropertyList(self.class, &proNumbers);
获取属性数量为2,分别是aaa和bbb。
这里就发现:
- 1.属性@property修饰的变量会自动创建带下划线的实例变量:如_bbb。
- 2.一般情况下,每个属性变量都对应一个实例变量,反之就不一定了。
如果在.m文件中加入以下代码:
@implementation ViewController
@synthesize bbb=_aaa;
...
@end
属性bbb会关联上实例变量_aaa,导致系统不会自动创建_bbb,这时候用class_copyIvarList运行时获取实例数量就是3,输出IvarName是:intV、_aaa、_testView。而属性变量还是aaa和bbb。
关联变量:
- (void)setNumPro:(int)numPro
{
objc_setAssociatedObject(self, @selector(numPro), @(numPro), OBJC_ASSOCIATION_ASSIGN);
}
- (int)numPro
{
return [objc_getAssociatedObject(self, _cmd) intValue];
}
这里通过运行时,给self关联了一个numPro变量,用法与属性一样,但是不提供实例变量(即不能使用_numPro),使用运行时class_copyIvarList
、class_copyPropertyList
都无法获取到该对象。