Re: Beginner Question Re: Memory Management
Re: Beginner Question Re: Memory Management
- Subject: Re: Beginner Question Re: Memory Management
- From: WT <email@hidden>
- Date: Tue, 23 Jun 2009 06:31:18 +0200
On Jun 23, 2009, at 4:47 AM, Graham Cox wrote:
On 23/06/2009, at 6:39 AM, Daniel Torrey wrote:
I'm looking at some sample iPhone code, and in the app delegate's
applicationDidFinishLaunching method, I see
// Set up the view controller
MyViewController *aViewController = [[MyViewController alloc]
initWithNibName:@"HelloWorld" bundle:[NSBundle mainBundle]];
self.myViewController = aViewController;
[aViewController release];
I'm a little confused - I see an allocation, followed by an
assignment, followed by a release. I think that the assignment is
really a call to a setter - the myViewController field is created
automagically using the @property/@synthesize syntax.
Since a release was sent to aViewController, what keeps that object
from being nuked at the end of the run loop? There must be another
retain happening somewhere, right?
Have a look at the definition for the property myViewController - it
should include the 'retain' attribute, which tells you that the
object is retained when it is assigned. In which case, it won't be
nuked.
I don't think you can see the code generated by @synthesise, as it
probably doesn't exist as Objective-C anywhere - but you can
disassemble it. I could be wrong though...
--Graham
Apropos the question raised by Daniel and Graham's response, and to
help other beginners, I'd like to relate a little true story that
happened to me just yesterday.
In the iPhone app I'm writing, I was doing some text processing on the
contents of a text field that the user can edit and in several places
I had the same piece of code:
[textFieldPreviousContent release];
textFieldPreviousContent = [textField.text retain];
So, I decided to make textFieldPreviousContent a property and
dutifully declared
@property (readwrite, nonatomic, retain) NSString*
textFieldPreviousContent;
in the header file and then synthesized it in the source file, like so:
@synthesize textFieldPreviousContent;
So far so good. I then replaced all the
[textFieldPreviousContent release];
textFieldPreviousContent = [textField.text retain];
sections with the much simpler
textFieldPreviousContent = textField.text;
the motivation being that I would not have to remember every time to
release textFieldPreviousContent nor to retain textField.text.
Ok, great, so now I built and ran and... my app crashed.
Huh? Wait... it was working fine before. Hmm... let me see. Property
declared correctly... it's readwrite... check. It's retained... check.
Property synthesized correctly... check.
What the heck???
So, after I scratched my head silly for several minutes, it suddenly
came to me. If I'm going to use a property, I *must* refer to it as
object.property rather than simply as property. In the specific
example I had, I should not have replaced all those repeated chunks of
code with
textFieldPreviousContent = textField.text;
but with
self.textFieldPreviousContent = textField.text;
Using
textFieldPreviousContent = textField.text;
meant that I was bypassing the very memory management I thought I was
getting for free by turning textFieldPreviousContent into a property.
Of course, my mistake implied that a) I was leaking the string pointed
to by textFieldPreviousContent and b) I was not retaining the string
returned by textField.text. And since that string is returned to me
auto-released, textFieldPreviousContent ended up pointing to a memory
location that was no longer valid by the time I used its contents. No
wonder my app crashed.
So, to all beginners out there, whenever you define a property,
remember always to refer to it, in its own class, by self.property -
at least when setting its value. It may be ok (depending on what
you're doing) to refer to it simply by property when *getting* its
value, but if the property is backed by an instance variable that is
an object (rather than a scalar type), it's *essential* that you refer
to it by prepending self when *setting* its value, or you'll not be
doing the memory management that you think you're doing.
Wagner
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden