1、@property 后面可以有哪些修饰符?
可以简单总结为以下几类:
•控制set方法的内存管理
retain:release旧值,retain新值(用于OC对象)
assign:直接赋值,不做任何内存管理(默认,用于非OC对象类型)
copy:release旧值,copy新值(一般用于NSString*)
•控制需不需生成set方法
readwrite:同时生成set方法和get方法(默认)
readonly:只会生成get方法
•多线程管理
atomic:性能低(默认)
nonatomic:性能高(最常用)
•控制set方法和get方法的名称
setter:设置set方法的名称,一定有个冒号:
getter:设置get方法的名称
2、什么情况使用 weak 关键字,相比 assign 有什么不同?
weak:(ARC下的)和(MRC)assign一样,weak当指向的内存释放掉后自动nil化,防止野指针
weak适用于OC对象,修饰的成员变量为弱指针类型;而assign适用于非OC对象类型
怎么用 copy 关键字?
copy 表示赋值特性,第一是setter方法将传入对象复制一份;第二是需要完全一份新的变量时。
3、这个写法会出什么问题:@property (copy) NSMutableArray *array;
程序会崩溃,报错:Attempt to mutate immutable object with xxx
使用copy属性,在赋值时,会默认做一次copy操作,会变成“不可变的类型”,
如果对于"可变类型"的属性,使用copy描述符定义后,那么赋值后,就是不可变的了!,如果我们在程序中尝试修改这个对象,就会出现错误。
4、如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
1>假设我们有两个类,Person类和Student类,那么在他们的.m文件里就可以这样写:
/**
自定义对象要实现copy功能
1> 遵守NSCopying协议
2> 实现- (id)copyWithZone:(NSZone *)zone
*/
@implementation Person
// 所有的copy方法,最终都会调用copyWithZone
// copy操作将一个对象,复制(当前对象的属性)给一个新的对象
- (id)copyWithZone:(NSZone *)zone
{
// 1> 实例化对象,self 是对象
// self.class能够保证继承的子类同样使用copy方法
Person *p = [[self.class alloc] init];
// 2> 给属性赋值
p.name = self.name;
p.age = self.age;
// 3> 返回新对象
return p;
}
如果父类遵守实现了这个协议,那么子类就不需要在遵守了,可以写成这样:
- (id)copyWithZone:(NSZone *)zone
{
// 直接调用父类的copy方法
Student *s = [super copyWithZone:zone];
// 赋值,只需要给子类的属性赋值即可!
s.no = self.no;
// 返回
return s;
}
2>重写带 copy 关键字的 setter
非ARC写法:
@implementation Person
- (void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name copy];
}
}
- (void)dealloc
{
[_name release];
_name = nil;
self.name = nil;
[super dealloc];
}
@end
ARC写法:
@implementation Person
- (void)setName:(NSString *)name
{
if (_name != name) {
_name = [name copy];
}
}
@end