selytch
selytch

Reputation: 535

Objective-c adding to array same instance with different properties

I'm trying the following code to create an instance, assign properties, add to array. Then, assigning new properties and adding again. However array will contain 2 identical objects (equal to the second one added). The class Message simply has several (nonatomic, retain) NSStrings/Integer properties. This probably has something to do with my understanding of pointer, can someone explain?

    self.messages=[[NSMutableArray alloc]init];
    Message *m=[[Message alloc]init];
    m.cb=@"2402";
    m.ck=1001;
    m.msg=@"as";
     [self.messages addObject:m];

    m.cb=@"2422";
    m.ck=1002;
    m.msg=@"aadfsdsdfdssdklsdflkh";
    [self.messages addObject:m];
    NSLog(@"%@",self.messages);

Upvotes: 0

Views: 246

Answers (3)

lnafziger
lnafziger

Reputation: 25740

When you add an object to an array, it does not add a copy of the object to the array, but instead just a reference to it. If you want two different objects, then you need to create two different objects instead of re-using the same one (or, as @Brendon points out, create a copy when you add it to your array).

To fix your example, the most common technique would be to add the following line right before you start modifying the properties for the second object:

m=[[Message alloc]init];

Or, use a second pointer and object instead of reusing m.

EDIT:
To add a copy, change [self.messages addObject:m]; to [self.messages addObject:[m copy]];, assuming that the Message class conforms to the NSCopying protocol.

Upvotes: 5

vikingosegundo
vikingosegundo

Reputation: 52227

You can either implement the NSCopy protocol — as mentioned by lnafziger — or just create new instances quite easily in a for loop.

«Two or more, use a for»
— Edsger W. Dijkstra

self.messages=[[NSMutableArray alloc] init];
NSArray *dataArray = @[ @{@"cb": @"2402", @"ck": @(1001), @"msg": @"as"}, 
                        @{@"cb": @"2422", @"ck": @(1002), @"msg": @"aadfsdsdfdssdklsdflkh"}
                      ];


for(NSDictionary *data in dataArray) {
    Message *m=[[Message alloc] init];
    m.cb = data[@"cb"];
    m.ck = [data[@"ck"] integerValue];
    m.msg = data[@"msg"];
    [self.messages addObject:m];
}

Upvotes: 0

Nikolai Ruhe
Nikolai Ruhe

Reputation: 81868

Yes, after executing the posted code self.messages contains the Message object twice, at indexes 0 and 1. That's not a problem, though. Arrays can contain any object, even themselves.

It seems that you want two distict objects, so you would just create a second Message.

Upvotes: 0

Related Questions