先写一个简单的自定义类
@interface PGYer : NSObject
@property(copy) NSString * uKey;
覆写init方法,为了方便起见我们把今天要说的东西放在init中
#import "PGYer.h"
#import <objc/runtime.h>
@implementation PGYer
@synthesize uKey = _uKey//此处是关键
-(instancetype)init{
NSLog(@"%@",NSStringFromClass([super class]));
if (self = [super init]) {
NSLog(@"%@",NSStringFromClass([self class]));
NSLog(@"%@",NSStringFromClass([super class]));
Ivar ivar = class_getInstanceVariable([self class], "uKey");
object_setIvar(self, ivar, @"1234546");
id uKey = object_getIvar(self, ivar);
NSLog(@"%@",uKey);
}
return self;
}
@end
我们来看一下打印信息
我们看到最下边打印为空。
那么我们来分析一下流程:
1通过class和属性名称获取c语言类型的属性变量Ivar
2.调object_setIvar给C类型的变量赋值
3调用object_getIvar从C类型的变量中获取属性值
整个流程看似完全没有问题
但是 我们忽视了一个问题
@synthesize uKey = _uKey//此处是关键
默认是这样绑定,因此,此时的属性名称的C写法是:_uKey
我么修改一下代码:
Ivar ivar = class_getInstanceVariable([self class], "_uKey");
然后我们看一些截图数据
@property(copy) NSString * uKey;转化为内部的_uKey
那么我们再次修改一下代码
再内部添加一个_uName属性
@interface PGYer : NSObject
{
NSString *_uKey;
NSString *_uName;
}
@property(copy) NSString * uKey;
@end我们再次通过Ivar进行赋值
Ivar nameVar = class_getInstanceVariable([self class], "_uName");
object_setIvar(self, nameVar, @"YuLongLe");
id aName = object_getIvar(self, nameVar);
NSLog(@"name %@",aName);
最后我们看一下debug模式下的情况:
我们可以看出成功的给_uName进行了赋值。
其实Xcode在之前的旧时代是
@propert和@synthesize是成对出现的,只是随着更新的加快,开发者已经无需手动添加synthesize,而是由编译器自动给添加了“_”,当然了,用户也可手动修改