我们申请一个类,在这个类如Person的时候申请一个属性,我们习惯性使用@property,如:
<pre>
@property (nonatomic, copy)NSString *name;
</pre>
因为他帮我们做了以下三件事:
<pre>
- 为当前类声明一个_name属性
- 为当前类在.h文件中生setter和getter方法的声明,方便我们使用点语法
3.在.m文件中生出setter方法和getter方法的根据修饰词生成getter和setter方法的实现
</pre>
其中@propery有两个属性一个是<code>@dynamic</code>另外一个是<code>@ synthesize</code>
dynamic:是负责在.m文件中产生setter和getter方法的实现,如果重写@dynamic此时,@property将不会给我们自动生成setter和getter方法的实现
synthesize:是负责在.m文件中产生_name(读:下划线属性)属性,如果重写synthesize那么将不会产生_name属性
dynamic
值得我们注意到是: 从写了<code>@dynamic</code>方法 当前类将不会自动生成getter和setter方法的实现。
<pre>@dynamic name;</pre>
在.m文件中用@dyanamic重写name,让系统不自动生成setter和getter方法的实现 unrecognized selector sent to instance 0x7fc971e0e940: 无法识别选择器发送的实例这里使用了.语法,说明SMPerson的文件中,是有setter和getter方法的声明的总结: 依旧可以使用点语法,说明在.h文件中生会自动生成setter和 getter方法的声明,但是程序奔溃了说找不到setter方法,说明没有产生setter方法的实现,也没有getter方法
@synthesize
是负责在.m文件中产生_name(读:下划线属性)属性,如果重写synthesize那么将不会产生_name属性。
注意,
- 我们通常有一个误区,如@property产生的是name属性。但是实际上他产生的是_name。
- 我们在外接通过点语法@property调用p1.name都时候都是间接的调用_name的值,通过p1.name = @"小白菜"的时候都是调用setter方法间接的给_name赋值
- 如果dynamic和@synthsize一起重写的话,会报错name已经生成
- 如果我们重写这个方法非_name的时候比如下图(第4点图),那么@property
利用运行时,打印出当前SMPerson类的所有属性,包括私有属性
<pre>
// 申请一个对象
SMPerson *p1 = [[SMPerson alloc] init];
// 为对象的name 赋值
p1.name = @"小白菜";
// 打印p1.name属性
NSLog(@"p1.name = %@",p1.name);
// 用outCount来记录SMPerson有多少个属性
unsigned int outCount = 0;
// 用运行时动态获取MSPerson的所有属性,包括私有属性 ,返回的是一个Ivar属性的数组
Ivar *ivarList = class_copyIvarList([SMPerson class], &outCount);
// 通过for循环打印出SMPerson的所有属性
for (NSInteger index = 0; index < outCount; index ++) {
// 在数组中拿出对应下标的ivar
Ivar var = ivarList[index];
// 转换成C语言字符串
const char *ivarCName = ivar_getName(var);
// 转换成OC的字符串
NSString *name = [NSString stringWithUTF8String:ivarCName];
// 打印对象 , 以及打印出当前对象的值
NSLog(@"当前属性名称%@, 当前属性的值:%@",name,[p1 valueForKey:name]);
}
</pre>
打印出SM所有属性的key和value注意: 26行p1.name和 41行的值名字都是小白菜,说明,当我们重写synthesize后,系统的做法大致如下图所示(用大致是因为后面还会有copy和assign,weak等修饰词,所以只是大概,用于理解我们)
<code>未完待续..........</code>
网友评论