views:

145

answers:

1

I'm relatively new to Objective C and while I've been trucking right along writing iPhone apps, I think I need some help understanding something.

I'm storing a dynamic list of strings in an NSMutableArray, which is a property of my main class. In my initialization I alloc and init to store 100 items:

stringList = [[NSMutableArray alloc] initWithCapacity:100];

As strings are acquired (from incoming data) I add them as objects to the array:

NSString *newString = [stringMaker makeStringFromData:data];
[stringList addObject:newString];

So to understand what's really happening here. If I've done this adding 5 times, what do I really have in the NSMutableArray? Just pointers to the 5 strings or the actual strings? I had assumed that addObject actually copied the data. If my stringMaker class were to start properly releasing things could I end up with pointers to nothing? Is there a better way to make sure that the strings in my list are safe from being released or repointed to something else? Or am I misunderstanding how this works?

I'm not currently having a problem with this part so far. But I'm a little shaky on leaks and releasing things.

What lead me to this is that I do have a problem where when I modify one of the strings by:

[stringList replaceObjectAtIndex: stringIndex withObject: stringMaker.lastStringUsed];

that after a while when I come back to access the object at that index, it's whatever lastStringUsed was last, not what it was when I replaced it. This indicates to me that all I did was set a pointer and didn't save the data at that pointer. Note that lastStringUsed is a property of the stringMaker class and is an NSMutableString.

So to be clear.. in stringMaker at various points I'm doing a:

 [lastStringUsed setString: someString];

(by the way does THAT actually move the data?)

Then in back in my main class I'm doing that replaceObjectAtIndex shown above. Then some other stringMaker method is resetting lastStringUsed. Then later when I access my stringList at that index it's the new lastStringUsed value and not whatever it was when I did the replaceObjectAtIndex.

EDIT - SOLVED FOR NOW - STILL NEED TO TAKE A NIGHT CLASS ON NSARRAYS AND STRINGS AND PROPERLY RETAINING AND RELEASING

What I did to fix it for now was to just allocate a new string...

NSString *replacementString = [[NSString alloc] initWithCapacity: 310];
[replacementString setString:stringMaker.lastStringUsed];
[stringList replaceObjectAtIndex:stringIndex withObject:replacementString];

Now the next time I change lastStringUsed it doesn't also change the one in the stringList.

A: 

When you add an object to an array or dictionary the object will be retained by that array or dictionary. Look at the retain count of the object you are placing into the array before and after you call addObject:

Nick
`NSDictionary` keys are copied instead of retained
rpetrich
Good point I should have made that clear but badweasel was asking about the object that is added not the key so I was focused on that.
Nick
Ok cool. Thanks. Any ideas for question 2? It's a little hard to explain what I'm trying to accomplish. But when I do that replace object at index I think it's putting stingMaker.lastStringUsed in there and not the pointer inside of lastStringUsed. Because later when I access that index it points to whatever lastStringUsed points to NOW, not what it pointed to back when I replaced it. Make sense?OR.. OR.. the string at that memory location is actually changing when I update lastStringUsed. Maybe every time I replace object with lastStringUsed it's assigning the exact same pointer.
badweasel
For me it is really hard to understand what you are trying to do and what string maker returns. Please share out a complete code example that demonstrates the problem or boil down the question.
Nick
I have 12,000+ lines of code in an iPhone app that will be submitted in a few days. I can't exactly post a snippit that would accurately describe what I'm trying to do. It would be more appropriate to write a small app to just demonstrate the one problem I'm having, which I don't have time for. I can think of 3 ways to fix it, 1- use NSDictionary instead of NSMutableArray, 2- allocate a new NSString when I replace the object, and 3- to allocate the exact memory I need for the 100 strings and move the data into that memory each time. SO I'll click solved and move on. Thanks ALL!
badweasel