NSArray的深浅拷贝
#import <Foundation/Foundation.h>
@interface NSArray (SNFoundation)
- (id)safeObjectAtIndex:(NSUInteger)index;
- (id)deepCopy;
- (id)mutableDeepCopy;
- (id)trueDeepCopy;
- (id)trueDeepMutableCopy;
@end


#import "NSArray+SNFoundation.h"
@implementation NSArray (SNFoundation)
- (id)safeObjectAtIndex:(NSUInteger)index
{
    if (self.count > index)
    {
        return [self objectAtIndex:index];
    }
    return nil;
}

//trueDeepCopyArray是完全意义上的深拷贝,而deepCopyArray则不是,对于deepCopyArray内的不可变元素其还是指针复制
- (id)deepCopy
{
    return [[NSArray alloc] initWithArray:self copyItems:YES];
}

- (id)trueDeepCopy
{
    return [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:self]];
}

- (id)mutableDeepCopy
{
    return [[NSMutableArray alloc] initWithArray:self copyItems:YES];
}

- (id)trueDeepMutableCopy
{
    return [[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:self]] mutableCopy];
}

@end

  

3.     自定义对象
如果是我们定义的对象,那么我们自己要实现NSCopying,NSMutableCopying这样就能调用copy和mutablecopy了。举个例子:
@interface MyObj : NSObject<NSCopying,NSMutableCopying>
{
         NSMutableString *name;
         NSString *imutableStr;
         int age;
}
@property (nonatomic, retain) NSMutableString *name;
@property (nonatomic, retain) NSString *imutableStr;
@property (nonatomic) int age;
@end
@implementation MyObj
@synthesize name;
@synthesize age;
@synthesize imutableStr;
- (id)init
{
         if (self = [super init])
         {
                   self.name = [[NSMutableString alloc]init];
                   self.imutableStr = [[NSString alloc]init];
                   age = -1;
         }
         return self;
}
- (void)dealloc
{
         [name release];
         [imutableStr release];
         [super dealloc];
}
- (id)copyWithZone:(NSZone *)zone
{
         MyObj *copy = [[[self class] allocWithZone:zone] init];
         copy->name = [name copy];
         copy->imutableStr = [imutableStr copy];
//       copy->name = [name copyWithZone:zone];;
//       copy->imutableStr = [name copyWithZone:zone];//
         copy->age = age;
         return copy;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
         MyObj *copy = NSCopyObject(self, 0, zone);
         copy->name = [self.name mutableCopy];
         copy->age = age;
         return copy;
}

  

4.自定义对象的拷贝

StudentObject.h

@interface peopleObject:NSObject<NSCopying,NSCoding>
@property(nonatomic,copy)NSString *num;
@end

@interface StudentObject : NSObject<NSCopying,NSMutableCopying,NSCoding>
@property(nonatomic,strong)NSMutableArray *itemList;  //包含的peopleobject对象,peopleObject对象必须实现NSCoding方法,不然会奔溃的
@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)NSString *title;
@property(nonatomic,copy)NSString *add;
@end


//
//  StudentObject.m
//  NSObject序列化
//
//  Created by goscam on 15/12/22.
//  Copyright © 2015年 goscam. All rights reserved.
//

#import "StudentObject.h"
#import "NSArray+SNFoundation.h"

@implementation peopleObject
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.num forKey:@"num"];
}

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        self.num = [coder decodeObjectForKey:@"num"];
    }
    return self;
}
@end

@implementation StudentObject

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    NSData *listData = [NSKeyedArchiver archivedDataWithRootObject:self.itemList];
    [aCoder encodeObject:listData forKey:@"list"];
    
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.title forKey:@"title"];
    [aCoder encodeObject:self.add forKey:@"add"];
}

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        NSData *listData = [coder decodeObjectForKey:@"list"];
        self.itemList = [NSKeyedUnarchiver unarchiveObjectWithData:listData];
        self.name = [coder decodeObjectForKey:@"name"];
        self.title = [coder decodeObjectForKey:@"title"];
        self.add = [coder decodeObjectForKey:@"add"];
    }
    return self;
}

//深拷贝
-(id) mutableCopyWithZone : (NSZone *) zone
{
    StudentObject *dto = [[StudentObject allocWithZone : zone] init];
    dto.itemList = [self.itemList trueDeepMutableCopy];
    dto.name = [self.name copy];
    dto.title = [self.title copy];
    dto.add = [self.add copy];
    return dto;
}

- (id)copyWithZone:(NSZone *)zone{
    StudentObject *dto = [[[self class] allocWithZone:zone] init];
    dto.itemList = [self.itemList trueDeepMutableCopy]; 
    dto.name = [self.name copy];
    dto.title = [self.title copy];
    dto.add = [self.add copy];
    return dto;
}

@end

 

1.调用copy方法进行深拷贝,就是两个不同的地址,没有调用的话,就是同一个对象

//
//  ViewController.m
//  NSObject序列化
//
//  Created by goscam on 15/12/22.
//  Copyright © 2015年 goscam. All rights reserved.
//

#import "ViewController.h"
#import "SecondViewController.h"
#import "StudentObject.h"
@interface ViewController ()
@property(nonatomic,strong)StudentObject *stuObject;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)next:(id)sender {
    SecondViewController *second = [[SecondViewController alloc]init];
    second.object = [_stuObject copy];    //使用copy方法调用copyWithZone方法进行深拷贝
    [self.navigationController pushViewController:second animated:YES];
}

- (IBAction)write:(id)sender {
    NSMutableArray *array = [[NSMutableArray alloc]init];
    StudentObject *object = [[StudentObject alloc]init];
    object.name = @"hello";
    object.add = @"wuhan";
    object.title = @"write";
    
    for (int i = 0; i < 10; i++) {
        peopleObject *people = [[peopleObject alloc]init];
        people.num = [NSString stringWithFormat:@"%d",i];
        [array addObject:people];
    }
    object.itemList = array ;
    NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"timerSwitch.data"];
    [NSKeyedArchiver archiveRootObject:[NSKeyedArchiver archivedDataWithRootObject:object] toFile:file];
    _stuObject = object;
    NSLog(@"写入成功");
}

- (IBAction)read:(id)sender {
    NSLog(@"stud",self.stuObject);
}

 

//
//  SecondViewController.m
//  NSObject序列化
//
//  Created by goscam on 15/12/22.
//  Copyright © 2015年 goscam. All rights reserved.
//

#import "SecondViewController.h"

@interface SecondViewController ()
@property(nonatomic,strong)UIButton *btn;
@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor orangeColor];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    _btn = button;
    [button setTitle:@"读取" forState:UIControlStateNormal];
    button.frame = CGRectMake(100, 200, 50, 50);
    [_btn addTarget:self action:@selector(read:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}

- (IBAction)read:(id)sender {
    NSLog(@"ddd");
    NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"timerSwitch.data"];
    NSData* data  = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
    if (data) {
        StudentObject *stuobject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        
        [_object.itemList removeObjectAtIndex:0];
        [_object.itemList removeObjectAtIndex:3];
        [_object.itemList removeObjectAtIndex:5];
    }
}

 

posted on 2015-12-11 14:46  pTrack  阅读(497)  评论(0)    收藏  举报