MRC下重写setter和getter方法
代码如下:
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@end
#import "Person.h"
@implementation Person
@synthesize name = _name;
- (void)setName:(NSString *)name{
if (_name != name) {
[_name release];
_name = [name copy];
}
}
- (NSString *)name{
return _name;
}
@end
copy和setter的选择
总结:
- 对于不可变对象(NSString、NSArray、NSDictionary等),使用copy修饰。
- 对于可变对象(NSMutableString、NSMutableArray、NSMutableDictionary等),使用strong修饰。
crash问题
把NSMutableArray用copy修饰有时就会crash,因为对这个数组进行了增删改操作,而copy后的数组变成了不可变数组NSArray,没有响应的增删改方法,所以对其进行增删改操作就会报错。
测试过程
以数组为例总结:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *arr_strong;
@property (nonatomic, copy) NSMutableArray *arr_copy;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *tempArr = [NSMutableArray arrayWithCapacity:0];
self.arr_strong = tempArr;
self.arr_copy = tempArr;
NSLog(@"arr_strong = %@\n arr_copy = %@",[self.arr_strong class],[self.arr_copy class]);
}
@end
输出结果:
arr_strong = __NSArrayM(可变数组)
arr_copy = __NSArray0(不可变数组)
所以此时如果对arr_copy进行增删改操作,会造成程序上的崩溃。
数据变化问题
条件:
针对数据变化的问题,会在将可变对象赋值给用strong修饰的不可变对象时产生。
测试代码:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSArray *arr_strong;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *tempArr = [NSMutableArray arrayWithCapacity:0];
[tempArr addObject:@"A"];
self.arr_strong = tempArr;
NSLog(@"arr_strong = %@",self.arr_strong);
[tempArr addObject:@"B"];
NSLog(@"arr_strong = %@",self.arr_strong);
}
@end
输出结果:
arr_strong = (
A
)
arr_strong = (
A,
B
)
如果把arr_strong属性修饰改成copy
输出结果:
arr_strong = (
A
)
arr_strong = (
A
)
copy collections
深拷贝和浅拷贝的区别
如下图所示:
浅拷贝就是指针拷贝;深拷贝就是内容拷贝。
copy和mutableCopy
1.不可变对象使用copy,是一个浅拷贝。
2.不可变对象使用mutableCopy,深拷贝。
3.可变对象copy和mutableCopy,都是深拷贝。
但是对于集合类对象来说:上面的深拷贝都是单层深拷贝,并非完全深拷贝。
集合类对象实现单层深拷贝
initWithArray:copyItems: 将第二个参数设置为YES即可深复制。
NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: YES];
deepCopyArray内部存储元素,对于不可变元素是指针拷贝,对于可变元素是内容拷贝。类似于内部每个元素调用了copy方法。
集合类对象实现完全深拷贝
将集合进行归档(archive),然后解档(unarchive)。
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];
参考资料:
Copying Collections
iPhone Dev:iOS开发之深拷贝与浅拷贝(mutableCopy与Copy)详解
Blog:copy 与 mutableCopy