3

With the following code, both items in the array are the same (the last item). What am I doing wrong that is causing this array to overwrite the values? I'm trying to use 1 object so I don't have to instantiate X number of objects.

self.myArray = [[NSMutableArray alloc] init];

MyObjClass *obj = [[MyObjClass alloc] init];
obj.firstName = @"First Name";
obj.lastName = @"Last Name";
obj.created = @"Dec 17 16:24";
[self.myArray addObject:obj];

obj.firstName = @"First Name2";
obj.lastName = @"Last Name2";
obj.created = @"Dec 18 7:41";
[self.myArray addObject:obj];

In MyObjClass.h I have @interface MyObjClass : NSObject. Is NSObject the wrong datatype?

Properties in MyObjClass.h:

@property (strong) NSString *firstName;
@property (strong) NSString *lastName;

And from MyObjClass.m:

@synthesize firstName, lastName;
0

5 Answers 5

4

The array isn't overwriting the values, you are in your code. You have one instance of the MyObjClass. *obj is a pointer to that objects and when you add it to the array twice, the array has two indexes that point to the object you added twice.

By setting the properties on obj, you're changing the values of that one object that both your *obj pointer and the array points to.

Why are you concerned about instantiating X objects? It sound like you want X objects which are in the array with distinct values.

Besides creating X objects, you can copy the first object, set the values then add that to the array but since you're setting all the values anyways, I'm not sure why you just wouldn't init a new object.

EDIT:

Based on your comment below, it looks like your concern of multiple objects is around memory management. When you add an object to an array, it retains the object so after you add it (if you're done with it in that scope), then release or autorelease it. When the array is released, it will call release on all the objects in the array. You need n objects whether you init or copy - you still have multiple. Release them and then let the array release when it's released.

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

1 Comment

Do I have to use unique objects each time? Is it possible to rework this code so it can work with only 1 object? If I use multiple objects, how do I release them from memory after I add them to the array?
1

You need to create a unique instance for each object that is added. Also the obj needs to be released in this method because adding it to the array retains it. However if you are using ARC no releasing is needed/allowed.

self.myArray = [[NSMutableArray alloc] init];

MyObjClass *obj;

obj = [[[MyObjClass alloc] init] autorelease];
obj.firstName = @"First Name";
obj.lastName = @"Last Name";
obj.created = @"Dec 17 16:24";
[self.myArray addObject:obj];

obj = [[[MyObjClass alloc] init] autorelease];
obj.firstName = @"First Name2";
obj.lastName = @"Last Name2";
obj.created = @"Dec 18 7:41";
[self.myArray addObject:obj];

2 Comments

There's no autorelease in ios5 anymore. I'm not sure if this just happens automatically now...
It is not iOS5 or even iOS4, it is ARC based projects (files actually) that do not allow autorelease, release or retain. Not everyone is using ARC for various reasons.
1

You are misunderstanding the -addObject: method and objects in general. You are adding a reference (pointer) to your instance of MyObjClass to the array. If you add the same instance twice, it doesn't make a difference. Also, as you only store a pointer to the object in the array, you always have the latest "version" of your object in the array.

You need to allocate two instances and add them both:

MyObjClass *object1 = ...;
[array addObject:object1];
MyObjClass *object2 = ...;
[array addObject:object2];

Comments

0

When adding objects to NSMutableArray, they are retained, not copied. If you don't want to modify your included object, use this sequence of code:

self.myArray = [[NSMutableArray alloc] init];

MyObjClass *obj = [[MyObjClass alloc] init];
obj.firstName = @"First Name";
obj.lastName = @"Last Name";
obj.created = @"Dec 17 16:24";
[self.myArray addObject:[[obj copy] autorelease]];

obj.firstName = @"First Name2";
obj.lastName = @"Last Name2";
obj.created = @"Dec 18 7:41";
[self.myArray addObject:obj]; // if you're using it further then you need to make a copy of it again

3 Comments

I can't use autorelease with ARC. Is it safe to just leave out autorelease or is there a new, different way to ensure that this gets released from memory? Also, using [obj copy] throws this error: unrecognized selector sent to instance
sorry, haven't looked into ARC yet.
Anyway, copy might not actually be such a good option, since you're overwriting all the previous values, so instead of calling copy, autorelease you can create a new instance and add it (there are some examples in the other comments)
0

Try set the properties in your MyObjClass class like this:

@property (copy) NSString *firstName;
@property (copy) NSString *lastName;
@property (copy) NSString *created;

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.