采用setter和getter很好的解决了封装和信息共享之间的矛盾,但是也带来一些副作用,最大的麻烦在于工作量大,假如一个类有10个要共享的变量,就要定义20个方法。Object-C 2.0中的属性机制为我们提供了便捷的设置和获取实例变量的方式,或者说:属性提供了一个默认的设置器和访问器的实现。
@property一条语句就起到了setter和getter的方法声明的作用。
@property NSString *homeAddress;//相当于声明了 设置器 和 访问器
//-(void)setHomeAddress:(NSString *)homeaddress;
//-(NSString *)homeaddress;
而@synthesize则起到了setter和getter的方法实现的作用。
@synthesize homeAddress = _homeAddress;
//-(void)setHomeAddress:(NSString *)homeAddress{
// _homeAddress = homeAddress;
//}
//-(NSString *)homeAddress{
// return _homeAddress;
//}
属性定义更简单的方法:
- 实例变量的声明可以省略掉
/*{
NSString *_name;
NSInteger _age;
NSString *_address;
NSString *_homeAddress;
}*/
@property NSString *homeAddress;//相当于声明了 设置器 和 访问器
@property (readonly,nonatomic,assign) NSInteger age;
@property (readwrite,nonatomic,strong) NSString *name;
- @synthesize可以省略掉,即
@synthesize homeAddress = _homeAddress;
可以省略掉,这个时候系统会为我们产生下划线的变量_homeAddress 来代替 homenAddress
。
示例:
@interface Newstudent : NSObject
{
NSString *_name;
NSInteger _age;
NSString *_address;
NSString *_homeAddress;
}
//以下注释掉的是设置器和访问器
//-(void)setName:(NSString *)name;
//-(NSString *)name;
//-(void)setAge:(NSInteger)age;
//-(NSInteger)age;
//-(void)setAddress:(NSString *)address;
//-(NSString *)address;
//属性的声明
@property NSString *homeAddress;//相当于声明了 设置器 和 访问器
@property (readonly,nonatomic,assign) NSInteger age;
@property (readwrite,nonatomic,strong) NSString *name;
/*访问读写,原子性,内存管理
1.存取方法名称
系统默认的存取方法名称 propertyName 和 setPropertyName,例如name 和 setname:方法,这样做方便采用点语法,可以采用默认的存取方式
setter = setterName
getter = getterName
注意,如果改变了getter 和 setter 方法名称,则必须提供自定的方法。
2.访问读写:
readonly 指明属性是只读的,系统只会产生getter,而不会产生setter方法
readwrite 指明属性是可读写的,这是默认的,因此可以省略
对于只读属性,如果试图通过点语法复制,会编译错误
原子性
automic 原子操作,这是默认的
nonautomic 非原子操作,一般就使用 nonautomic,但是没有办法保证在多线程环境下不出错
内存管理
retain 会通过retain来持有目标对象,之前的对象会接收到释放的消息
copy 会通过copy复制对象,之前的对象会接收到释放的消息
assign 采用简单的赋值方法,这是默认的方法
strong 表示强引用关系,即拥有目标对象的所有权
weak 表示弱引用关系,不拥有目标对象的所有权。当目标对象被摧毁之后,属性值会被自动设为nil
strong 相当于 retain 或者 copy,对象要用retain,copy,strong来描述
weak 相当于 assign 基本数据类型要用到 assign 或者 weak 来描述
*/
//便利初始化函数
-(id)initWithName:(NSString *)name
Age:(NSInteger)age
Address:(NSString *)address;
//便利构造器
+(id)newstudentWithName:(NSString *)name
Age:(NSInteger)age
Address:(NSString *)address;
@implementation Newstudent
-(void)setName:(NSString *)name{
_name = name;
}
-(NSString *)name{
return _name;
}
//-(void)setAddress:(NSString *)address{
// _address = address;
//}
-(NSString *)address{
return _address;
}
//相当于设置器 和 访问器 的实现
//@synthesize homeAddress = _homeAddress;
/*
注意:如果我们把 @synthesize 注释掉,这个时候系统会为我们产生下划线的变量。
_homeAddress 来代替 homenAddress
*/
//-(void)setAge:(NSInteger)age{
// _age = age;
//}
-(NSInteger)age{
return _age;
}
-(id)initWithName:(NSString *)name
Age:(NSInteger)age
Address:(NSString *)address{
if (self = [super init]) {
// _name = name;
self.name = name;
// _age = age;
// self.age = age;只读,不可设置值
_address = address;
}
return self;
}
+(id)newstudentWithName:(NSString *)name
Age:(NSInteger)age
Address:(NSString *)address
{
Newstudent *newstu = [[Newstudent alloc]initWithName:name Age:age Address:address];
return newstu;
}
点语法是为了方便书写而发明的,本质上是getter和setter的另一种写法,例如:
stu1.name = @"李明";
aName = stu.name;
-(id)initWithName:(NSString *)name
Age:(NSInteger)age
Address:(NSString *)address{
if (self = [super init]) {
// _name = name;
self.name = name;
// _age = age;
// self.age = age;只读,不可设置值
_address = address;
属性的重定义有如下应用模式:
- 从一个不可变的父类产生可变的子类
- 一个类有只读的公开属性和可读写的私有的属性