Question

I would like to know how can i deep copy of custom array without pointing old array. I have checked almost all stack overflow questions but didn't find any solution. Please help to copy array without pointing old array so My new array operations(add,remove)don't affect the original/old array.

Here is my main array declaration.

@property (nonatomic, strong) NSArray *secArray;

adding custom objects to array

      NSMutableArray *secDataArray = [NSMutableArray array];
     [SetRequest.SetMembers enumerateObjectsUsingBlock:^(SetMember *member, NSUInteger idx, BOOL *stop) {

        SecData *secData = [secDataArray lastObject];
        if(!secData || ![secData.secTitle isEqualToString:member.setHeader])
        {
          secData = [secData secDataWithTitle:member.setHeader
                                                     lines:@[member]];
          secData.open = YES;
          [secDataArray addObject:secData];
        }
        else
        {
          [secData.lines addObject:member];
        }
    }];

        self.secArray = [secDataArray copy];// copy secDatarray to my main array(secArray)

deep Copy of custom array in to new array

 NSArray *newSecarray=[[NSMutableArray alloc] initWithArray:secArray copyItems:YES];

But remove data from new array also removes the data from old array.

SecData *dataoldarraydata = [self.secArray objectAtIndex:0];
SecData *datnewarraydata = [newSecarray objectAtIndex:0];

[datnewarraydata.rows removeLastObject];

NSLog (@"oldarraydata=%d",[secArray.lines count]); //Out Put = 33 (It should be 34 for as i don't want delete data from original array)
NSLog (@"newarraydata=%d",[newSecarray.lines count]); //Out Put = 33

//Here is my custom secData class.

//secData.h file

@interface secData : NSObject

@property (nonatomic, strong) NSMutableArray *lines;
@property (nonatomic, strong) NSString *secTitle;
@property (nonatomic, strong) NSString *secIndexTitle;
@property (nonatomic, assign) BOOL open;

+ (id) secDataWithTitle:(NSString*)inTitle lines:(NSArray*)inLines;
+ (id) secDataWithLines:(NSArray*)inLines;
+ (id)copy;

@end

//secData.m file

#import "SecData.h"

@implementation SecData

@synthesize lines;

 + (id) secWithLines:(NSArray*)inLines 
 {
return [self secDataWithTitle:nil lines:inlines];
 }

+ (id) secDataWithTitle:(NSString*)inTitle Lines:(NSArray*)inLines
{
    SecData *sec = (SecData *)[[self alloc] init];
    [sec setSecTitle:inTitle];

    NSMutableArray *mutableCopyArray = [[NSMutableArray alloc] initWithArray:inLines];
    [sec setLines:mutableCopyArray];

    return sec;
}

- (NSMutableArray*)lines
{
    if(! lines)
    {
        self. lines = [NSMutableArray array];
    }
    return lines;
}

- (void) setLines:(NSMutableArray *)aArray
{
    NSMutableArray *newArray = aArray;

    if(![aArray isKindOfClass:[NSMutableArray class]])
        newArray = [NSMutableArray arrayWithArray:aArray];

    lines = newArray;
}

- (id)copyWithZone: (NSZone *)zone
{
    id  seccopy = [[[self class] alloc]init];
    if(seccopy ) {

        NSMutableArray *temp = [[NSMutableArray alloc]initWithArray:self.lines copyItems:YES];

        [seccopy setSecTitle:self.secTitle];
        [seccopy setLines:self.lines];
    }


    return seccopy;
}

@end
Was it helpful?

Solution

If you need a true deep copy then there is also a way in which you can archive and then unarchive the collection. You will be required to implement NSCoding protocol in your classes to be archived/unarchived. This is not an efficient way but it does provide true deep copy i.e., your arrays will be totally different.

Use this code for copying:

NSArray* newSecArray = [NSKeyedUnarchiver unarchiveObjectWithData:
          [NSKeyedArchiver archivedDataWithRootObject:secArray]];

You can also see Apple Docs about shallow and deep copying. Apple also states this method for true deep copying in its docs.

Here's the link for Archives and Serializations Programming Guide about encode/decode objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top