属性
采用 setter 和 getter确实很好地解决了封装和信息共享之间的矛盾,但是也带来一系列副作用,最大的麻烦在于工作量大。假如一个类有30个变量需要共享,那么工作量则会非常繁琐,这个时候就需要用到属性。
在头文件中代替方法的声明部分,使用 @property 符号。
例如 :
在接口文件写入
@interface Student : NSObject
{
NSString *name;
int age;
}
//使用属性声明可以写成,两行代码直接声明的成员变量name,age的设置器与访问器
@property (readwrite,nonatomic,copy) NSString *name;
@property int age;
//声明 便利初始化函数 以及 便利构造器
- (id)initWithName:(NSString *)name
Age:(NSInteger)age;
+ (id)studentWithName:(NSString *)name
Age:(NSInteger)age;
在实现文件中写入
//注意:如果我们把 @synthesize 注释,系统会为我们产生下划线开头的变量。
//相当于 设置器 和 访问器 的实现,也叫属性的实现
@synthesize homeAddress = _homeAddress;
- (id)initWithName:(NSString *)name
Age:(NSInteger)age{
if (self = [super init]) {
self.name = name;
self.age = age;
}
return self;
}
+ (id)studentWithName:(NSString *)name
Age:(NSInteger)age{
NewStudent *student = [[NewStudent alloc]initWithName:name
Age:age ];
return student;
}
在main.m里面写入
NewStudent *newstudent = [[NewStudent alloc] init];
newstudent.name = @"Jimuta";
newstudent.age = 18;
NSLog(@"name = %@, age = %ld",newstudent.name,new student.age);
// 点('.')语法本质就是 设置器 与 访问器
运行结果为:name = Jimuta , age = 18
property的有关语法
属性的定义还有很多语法,可以改变存取方法的名称、可读写性、以及重新定义属性等
- 存取方法名称
- 可读写性
- 原子性
- 内存管理
-存取方法名称
系统就默认的存取方法名称 PropertyName 和 setPorpertyName , 例如 name 和 setName:方法,
这样做方便采用点语法,可以采用默认的存取方式
getter = getterName
setter = setterName
注意,如果改变了 getter 和 setter 方法名称,则必须提供自定的方法
-访问读写:
readonly 指明属性是只读的,系统只会产生 getter 而不会产生 setter方法
readwrite 指明属性是可读写的,这是默认,可以省略
对于只读属性,如果试图通过点语法赋值,会报错
-原子性
atomic 原子操作,这是默认的
nonatomic 非原子操作,一般使用 nonatomic ,但是没有办法保证在多线程环境下不出错
-内存管理
retain 会通过 retain 来持有目标对象,之前的对象会接收到释放的消息
copy 会通过 copy 复制对象,之前的对象会接收到释放的信息
assign 表明采用简单的赋值方法,这是默认的
strong 表示强引用关系,即拥有目标对象的所有权
weak 表示弱引用关系,不拥有目标对象的所有权。当目标对象被销毁之后,属性值会被自动设为nil
注意:
strong 相当于 retain 或者 copy,对象要用 retain, copy, strong来描述
weak 相当于 assign ,基本数据类型要用 assign 或者 weak 来描述