4
votes

I'm new to iPhone developement and I did a lot of reading before jumping into my first app. All this reading made me understand that correct memory management is a big deal, so I want to do things right.

I've just finished my first app and started testing it for leaks. There were plenty :) I've changed the code to solve the leaks and then started getting BAD_ACCESS exceptions. Now to my questions:

  • I have a UITextView object, let's call it 'utv'. I saw that its 'text' field is defined as follows:

    @property (nonatomic, copy) NSString* text;

If I write the following line of code:

utv.text = [NSString stringWithString:@"Blabla"];

I shouldn't be concerned about the autorelease pool releasing the string, right? Because it uses copy?

  • What if it was defined as

    @property (nonatomic, retain) NSString* text;

    Should I still not be concerned about the autorelease pool, becuase the retain raised the refernce count by 1?

  • Can I know when the autorealease pool will release a string I create with stringWithString instead of initWithString?

Thanks! Eli

5
Just a comment outside the main question. Today I've discovered WWDC2010 video session 311: Advanced Memory Analysis with Instruments. I'm also still a beginner and it gave me a lot of understanding how to chase leaks, abandoned mem and how to cope with memory warnings.matm

5 Answers

3
votes

You've pretty much answered your own question, in my opinion. If the property was a retain one, new value will be sent a retain message in its synthesized setter method, so you should not worry about it :)

Here are the code differences between setters to help you understand how they deal with memory:

// assign 
property = newValue;

// retain
if (property != newValue) {
    [property release]; 
    property = [newValue retain];
}

// copy 
if (property != newValue) {
    [property release]; 
    property = [newValue copy];
}
1
votes

Don't think of memory management in terms of autorelease pools or retain counts. Think of it in terms of whether you own an object or not. If you own it, you're responsible for releasing it.

Both of these lines create retained properties:

@property (nonatomic, copy) NSString *text;
@property (nonatomic, retain) NSString *otherText;

The copy just means retain a copy, not the original. Both of these properties are memory managed, so you don't have to worry about retains or releases in normal usage.

self.text = string1; // this retains a copy of string1
self.text = string2 // this releases the copy of string1 and retains the copy of string2
self.text = nil; // this releases the copy of string2

You own self.text and self.otherText, so you need to release them in dealloc.

If you don't alloc, new, copy, or retain an object, you don't own it. If you don't own it, but you need to guarantee it sticks around beyond the end of the run loop, claim ownership by retaining it.

0
votes

You are correct. You should not be concerned with the autorelease pool when the property set as retain or copy. You will not know when an NSAutoreleasePool will release your string but you are safe to assume that you can use it within the same method that is declared freely. Each thread is supposed to have its own NSAutoReleasePool which can be drained at any time but is usually drained at the beginning of each run loop.

0
votes

Anything you retain, you need to release. You cannot depend on when autorelease will release whats in the pool.

This question has been asked before. Here's the easy answer

http://cocoadevcentral.com/d/learn_objectivec/

0
votes

This is a good read for memory management
Hope this helps someone.!