@property
@property的含义
用于声明成员变量的 getter/setter方法,编译器实际上是做了两件事,生成getter 和 setter,给类中添加名为属性名前加下划线的实例变量。这个过程叫做自动合成
@property=getter方法+setter方法+Ivar(带下划线的实列变量)
@property的使用
以下代码相当于声明了实现了set方法setName、get方法name,以及实列变量_name
@interface ViewController : UIViewController
@property (nonatomic,copy) NSString* name;
@end
等价于下面代码:
@interface ViewController : UIViewController
{
NSString* _name;
}
- (void)setName:(NSString*)name;
- (NSString*)name;
@end
@implementation ViewController
- (void)setName:(NSString*)newTestVar
{
_name = name;
}
- (NSString*)name
{
return _name;
}
@end
总结
什么时候不会使用自动合成?
- 同时重写了setter和getter时。
- 重写了只读属性的getter时。
- 使用了@dynamic时。
- 在@protocol中定义的所有属性。
- 在category中定义的所有属性。
- 重载的属性
@synthesize
@synthesize的含义
本质是@synthesize可以指定set/get方法的实现,际上就相当于完成自动合成的过程,并且可以让程序员指定实例变量,如果不指定实例变量,那么实例变量默认是属性名。
@synthesize的使用
- @synthesize默认会生成一个同名的成员变量作为set/get的目标。
@interface ViewController : UIViewController
@property (nonatomic,copy) NSString* name;
@end
@implementation ViewController
@synthesize name;
@end
等价于下面代码:
@interface ViewController : UIViewController
{
NSString* name;
}
- (void)setName:(NSString*)name;
- (NSString*)name;
@end
@implementation ViewController
- (void)setName:(NSString*)newTestVar
{
name = name;
}
- (NSString*)name
{
return name;
}
@end
- 当然也可以指定一个成员变量
@interface ViewController : UIViewController
@property (nonatomic,copy) NSString* name;
@end
@implementation ViewController
@synthesize name=_testName;
@end
@interface ViewController : UIViewController
{
NSString* name;
}
- (void)setName:(NSString*)name;
- (NSString*)name;
@end
@implementation ViewController
- (void)setName:(NSString*)newTestVar
{
_testName = name;
}
- (NSString*)name
{
_testName name;
}
@end
官方规范的做法
每个属性对应一个以_开头的成员变量,和只写一个@property作用是一样的。
@interface ViewController : UIViewController
{
NSString* _name;
}
@property (nonatomic,copy) NSString *name;
@end
@implementation ViewController
@synthesize name = _name;
@end
@dynamic
@dynamic的作用是告诉编译器,此属性对应的set/get方法将会被动态提供。
@interface ViewController : UIViewController
@property (nonatomic,copy) NSString* name;
@end
@implementation ViewController
@dynamic name;
@end
如果没有提供name对应的setter方法和getter方法,会有什么问题:
- 编译的时候没问题,但是当程序运行到instance.name =someVar,由于缺setter方法会导致程序崩溃。
- 当运行到 name = var时,由于缺getter方法同样会导致崩溃。
编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。