属性声明
@property (nonatomic, copy) NSString *name;
系统帮我们做了三件事:
-(void)setName:(NSString *)name;
-(NSString *)name;
_name;
setter,getter ,成员变量
属性 = setter + getter + 成员变量; (ps: setter/getter的调用只能通过点语法)
//getter 成员变量
@property (nonatomic, copy , readonly) NSString *name;
// setter getter 成员变量 readwrite是默认
@property (nonatomic, copy , readwrite) NSString *name;
//setter/getter 重命名
@property (nonatomic, copy , getter=getterName, setter=setterName:) NSString *name;
如果我们自己重写了setter和getter,系统就不会为我们创建成员变量:
-(void)test{
//Use of undeclared identifier '_name'
_name = @"";
}
-(void)setName:(NSString *)name{
}
-(NSString *)name{
return @"";
}
就不能直接使用成员变量。解决方案通过下面方法:
@synthesize
@synthesize name = _name; 属性名 = 成员变量名
-(void)test{
_name = @"";
}
-(void)setName:(NSString *)name{
_name = name;
}
-(NSString *)name{
return @"";
}
@synthesize是如果没有自定义setter和getter,编译器会帮你生成成员变量;
@dynamic 是告诉编译器我自己实现setter和getter ,不用帮我加setter和getter, 如果没有自己实现setter和getter则不能使用点语法访问该属性。
@dynamic 修饰属性编译器不生成setter,getter和成员变量。
@interface CPerson ()
@property (nonatomic, copy) NSString *name;
@end
@implementation CPerson
@dynamic name;
@end
Class personClass = NSClassFromString(@"CPerson");
unsigned int ivarCount = 0;
Ivar *ivarList = class_copyIvarList(personClass, &ivarCount);
for (int i = 0; i < ivarCount; i++) {
NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivarList[i])];
NSLog(@"ivarName : %@", ivarName);
}
unsigned int methodCount = 0;
Method *methodList = class_copyMethodList(personClass, &methodCount);
for (int i = 0; i < methodCount; i++) {
NSString *methodName = NSStringFromSelector(method_getName(methodList[i]));
NSLog(@"methodName : %@", methodName);
}