2

I have two arrays. First contains custom objects. Now I want to copy all object of first array in another array. For that I am using below code.

Arays.

arr_post=[[NSMutableArray alloc]init];
copy_arr_user_post=[[NSMutableArray alloc]init];

am adding the objects into them like this.

for(i=0;i<[arr_main count];i++)
{
    Post *obj=[[Post alloc]init];
    obj.name=@"abc";
    obj.category=@"social";
   [arr_post addObject:obj];


}

Now I am copying to another array like this

 [arr_post addObject:user_post];
 Post *objectCopy = [user_post copy]; //create a copy of our object
 [copy_arr_user_post addObject: objectCopy]; //insert copy into other array

In Post.h

@interface Post : NSObject<NSCopying>

In Post.m

- (id)copyWithZone:(NSZone *)zone
{
    // Copying code here.
    Post *another =[[[self class] allocWithZone:zone] init];
    another.id=self.id;
    another.category=self.category;
    return another;
}

But it does not copy objects I get null value. Why?

4
  • Clarify your issue Where in the posted code are you getting a nil value? Which code is not working as expected? Commented Oct 23, 2015 at 5:22
  • I think this is a very useful link for studying about deep copying collections: developer.apple.com/library/mac/documentation/Cocoa/Conceptual/… Commented Oct 23, 2015 at 5:46
  • i am getting nil value when i get the objects from second array Commented Oct 23, 2015 at 6:47
  • You can't store nil objects in an array so the array itself must be nil. Commented Oct 23, 2015 at 13:59

2 Answers 2

2

One method that I find faster than NSCopyng

-Create an NSObject category with this two method

#import <objc/runtime.h>
-(id)deepCopy
{
NSArray *tmpArray = @[self];
NSData *buffer = [NSKeyedArchiver archivedDataWithRootObject:tmpArray];
return [NSKeyedUnarchiver unarchiveObjectWithData:buffer][0];
}

- (NSMutableArray *)allProperties
{
    NSMutableArray *props = [NSMutableArray array];
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];

        //Excluding all readOnly properties
        unsigned int numOfAttributes;
        objc_property_attribute_t *propertyAttributes = property_copyAttributeList(property, &numOfAttributes);

        BOOL foundReadonly = NO;

        for ( unsigned int ai = 0; ai < numOfAttributes; ai++ )
        {
            switch (propertyAttributes[ai].name[0]) {
                case 'T': // type
                    break;
                case 'R': // readonly
                    foundReadonly = YES;
                    break;
                case 'C': // copy
                    break;
                case '&': // retain
                    break;
                case 'N': // nonatomic
                    break;
                case 'G': // custom getter
                    break;
                case 'S': // custom setter
                    break;
                case 'D': // dynamic
                    break;
                default:
                    break;
            }
        }
        free(propertyAttributes);

        if (!foundReadonly)
        {
            NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSASCIIStringEncoding];
            [props addObject:propertyName];
        }
    }
    free(properties);
    return props;
}

-Make your object conforms to NSCoding

#pragma mark - NSCoding
- (instancetype)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (self)
    {
        NSArray *keys = [self allProperties];

        for (NSString *key in keys)
        {
            [self setValue:[decoder decodeObjectForKey:key] forKey:key] ;
        }

    }
    return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    NSArray *keys = [self allProperties];

    for (NSString *key in keys)
    {
        [aCoder encodeObject:[self valueForKey:key] forKey:key];
    }
}

-Import the category

Now you are able to copy any kinds of object

MYObject *copy = [originalObject deepCopy];
NSArray *arrayWithCopiedObjects = [originalArray deepCopy];

etc....

Sign up to request clarification or add additional context in comments.

2 Comments

"Now you are able to copy any kind of object" - No. Now you can copy any object and its properties. This only works on simple objects that only need properties to be copied. I have many classes that this wouldn't work on.
This also doesn't recursively do deep copies.
1

Try

NSMutableArray *  arr_post=[[NSMutableArray alloc]init];
NSMutableArray * copy_arr_user_post=[[NSMutableArray alloc]init];
for(int i=0;i<3;i++)
{
    Post *obj=[[Post alloc]init];
    obj.name=@"abc";
    obj.category=@"social";
    [arr_post addObject:obj];
}

[arr_post enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    [copy_arr_user_post addObject:[obj copy]];
}];
Post * temp = [arr_post objectAtIndex:0];
temp.name = @"123";
NSLog(@"%@",arr_post);
NSLog(@"%@",copy_arr_user_post);

And log

2015-10-23 13:25:31.994 OCTest[1784:130931] (
"123 social",
"abc social",
"abc social"
)
2015-10-23 13:25:31.995 OCTest[1784:130931] (
"abc social",
"abc social",
"abc social"
)

I add description for debugging

-(NSString *)description{
    return [NSString stringWithFormat:@"%@ %@",self.name,self.category];
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.