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