2

Let's say I've got an array with strings.

NSArray *names = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];

What I want is to initiate objects of some custom class and them add them to a mutable array. I'm using a custom init method that takes a string argument.

To be more specific, I want to [SomeClass alloc] initWithName: aName] and add the resulting object to a NSMutableArray.

I'm thinking of using Objective-C fast enumeration. So what I get is:

NSMutableArray *objects = [NSMutableArray arrayWithCapacity: [names count];

for (NSString *name in names) {
    [objects addObject: [[[SomeClass alloc] initWithName: name] autorelease]];
}

The problem is that I can't add nil to the array and I don't like exception handling. However, my initiation method may return nil. So I decide to check first before adding (prevention). My new for-in-loop is:

SomeClass *someObject;

for (NSString *name in names) {
    someObject = [[[SomeClass alloc] initWithName: name] autorelease];
    if (someObject) {
        [objects addObject: someObject];
    }
}

Now, instead of immediately passing the new object to the array, I'm setting up a pointer someObject first and then passing the pointer to the array instead.

This example raises a question to me. When I someObject = [[[SomeClass alloc] initWithName: name] autorelease] in the loop, do the existing objects (which are added using the same pointer) in the array change too?

To put it in other words: does the addObject: (id)someObject method make a new internal copy of the pointer I pass or do I have to create a copy of the pointer — I don't know how — and pass the copy myself?

Thanks a lot! :-)

Constantino Tsarouhas
  • 6,846
  • 6
  • 43
  • 54

4 Answers4

3

It's fine to reuse someObject; if you think about it, you're already reusing name each time you go through the loop.

-addObject: may or may not copy the object that you pass in. (It doesn't -- it retains the object rather than copying it, but it's conceivable that some NSMutableArray subclass could copy instead.) The important thing is that this code really shouldn't care about what -addObject: does.

Also, don't lose sight of the distinction between a pointer and the object that it points to. Pointers are just references, and a pointer is copied each time you pass it into a method or function. (Like C, Objective-C passes parameters by value, so passing a pointer into a method results in putting the value of the pointer on the stack.) The object itself isn't copied, however.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Don't worry about memory leaks. I didn't add releases here in order to keep the examples short and to the point as much as possible. Thank you. – Constantino Tsarouhas May 12 '11 at 14:53
  • @King C, that's understandable, but remember that others will read this question and answers in the future. I'd encourage anyone to always leave the memory management in. That said, my answer above is quite wrong -- I missed your autorelease in the code above, so the release that I added will cause a crash. Yikes! I'll edit my answer to correct that. – Caleb May 12 '11 at 14:58
2

Short answer: no, you don't have to worry about reusing someObject.

Slightly longer answer: the assignment—someObject = ... assigns a new pointer value to the someObject variable; addObject: is then getting that value, not the address of someObject itself.

Noah Witherspoon
  • 57,021
  • 16
  • 130
  • 131
2

I think you're getting confused in the concept of pointer here. When you say someObject = [[[SomeClass alloc] init... you are basically pointing the someObject pointer to a new object. So to answer your question- your current code is fine.

As for whether arrays maintain copies of the objects added to them - NO, the array retains the object you add to it. However, that doesn't matter to your code above.

Tejas
  • 651
  • 5
  • 10
0

Three20 provides the answer!

Constantino Tsarouhas
  • 6,846
  • 6
  • 43
  • 54