Question

Line 1: First.h
Line 2: @property (nonatomic, retain) NSString *name;

Line  3: First.m
Line  4: @synthesize name;
Line  5: -(void)viewDidLoad()
Line  6: {
Line  7:     name = [NSString stringWithString:@"Hello"];
Line  8:                          OR
Line  9:     self.name = [[NSString alloc]initWithString:@"Hello"]; 
Line 10:                          OR
Line 11:  }
Line 12:-(void)dealloc()
Line 13: {
Line 14: [name release];
Line 14: } 

Question 1:
If I follow line number 7 everything is fine and if I used line number 9 Memory leakage is there. As I know self is point to current object and if I used self.object or simply object no more difference.

Question 2: And if I used

@synthesize name = _name;

Then which one is for setting the value of name and which one is for get the value? Difference between:

name = [NSString stringWithString:@"Hello"];
            OR
self.name = [NSString stringWithString:@"Hello"];
            OR
_name = [NSString stringWithString:@"Hello"];

Question 3:
If I create any property is there any need to alloc in the memory as I allocated showing the memory leakage?

Was it helpful?

Solution

QUESTION 1: if I follow line number 7 everything is fine and if I used line number 9 Memory leakage is there. As I know self is point to current object and if I used self.object or simply object no more difference.

Line  7:     name = [NSString stringWithString:@"Hello"];
Line  8:                          OR
Line  9:     self.name = [[NSString alloc]initWithString:@"Hello"]; 

On line 7 you are using a convenience constructor which returns an autoreleased object and assigning the object directly to your name ivar; now, it is ok to assign an autoreleased object to a retain property, but it is incorrect to assign an autoreleased object directly to an ivar without also explicitly retaining it:

name = [[NSString stringWithString:@"Hello"] retain];

On line 9 you are using alloc/init which gives you a retained object: it is correct to assign such an object directly to an ivar, but you should autorelease it before assigning to a retain property, e.g.:

self.name = [[[NSString alloc]initWithString:@"Hello"] autorelease]; 

You can reason about this in terms of the object retain count:

  1. a convenience constructor will set the retain count to 1, but this will be later on automatically decreased by a release call done by the framework;

  2. alloc/init will give you a retain count of 1 that will not be decreased unless you explicitly call release;

  3. When an object retain count goes to 0, then it will be deallocated.

Reasoning in terms of retain count is just a way to look at this whole matter of memory management and to understand what is going on deep in the framework; in no case this is a proper way to analyze your objects lifecycle, though.

then which one is for setting the value of name and which one is for get the value? Difference between name = [NSString stringWithString:@"Hello"]; OR self.name = [NSString stringWithString:@"Hello"]; OR _name = [NSString stringWithString:@"Hello"];

name = [NSString stringWithString:@"Hello"];

and

_name = [NSString stringWithString:@"Hello"];

are just the same thing in the two cases given. This will bypass the property setter(/getter) method and assign directly to the ivar. In this case, your app would sooner or later crash because you are assigning an autoreleased object to the ivar directly. This would be correct:

_name = [[NSString stringWithString:@"Hello"] retain];

or

_name = [[NSString alloc] initWithString:@"Hello"];

Note that in a program where you declare your ivar as _name, you cannot use name to refer to it; you can use name to directly refer to the ivar if you declared only the property without explicitly specifying the ivar like you did for question 1 (in this case, name would be the ivar automatically generated by the compiler for you).

On the other hand:

self.name = [NSString stringWithString:@"Hello"]; 

will use the property accessor method (actually, the setter); since your property is declared as retain, it is ok to assign to it the autoreleased variable returned by the convenience constructor stringWithString:.

QUESTION 3: if I create any property is there any need to alloc in the memory as I allocated showing the memory leakage.

This is not really clear to me.

A good document where to read about the basic of memory management is: Memory Management Policy and also Practical Memory Management from Apple's Advanced Memory Management Programming Guide.

OTHER TIPS

To respond the first question: you get the leak because initializing the string with the alloc method you are retaining the object created but you don't release the object after, so you get the leak, while creating the string with the stringWithString you get an autoreleased object that is released automatically by the autorelease pool. Note that in your example at line 9 you are initializing the object and passing it to the setter of the property, things would have been different if you have used the ivar ...

To respond your second question: you are synthesizing the property name and associating it to the internal variable(ivar) named _name, so internally in your class you can access the value of the property using the ivar _name.

I strongly suggest to read the Apple documentation about memory management.

First some background, a summary only of the concepts for MRC:

Memory management is all about ownership; as long as you own an object it will exist, some time after you relinquish ownership the object will be destroyed. Any references you maintain to an object are effectively invalid and should not be used once you've relinquished ownership.

Ownership is not exclusive but follows a shared model, there can be more than one owner at any given time and only when an object has no owners does it become available to be destroyed.

If you only need to use an object temporarily, e.g. within a single block of code, you do not always need to take ownership. This is partly a consequence of how ownership and be relinquished; rather than immediately relinquishing ownership you can request ownership is relinquished later.

Later occurs at certain points in the execution of an application and unless any such points are manually added there is one such point after the execution of each cycle through the run loop.

Ownership is asserted through a retain call or calling a method which returns an object you own - most commonly alloc, but also copy and others. Ownership is relinquished using a call to release; and is relinquished later using a call to autorelease.

Question 1:

Line  7:     name = [NSString stringWithString:@"Hello"];
Line  8:                          OR
Line  9:     self.name = [[NSString alloc] initWithString:@"Hello"]; 

The right hand side (RHS) of line 7 returns a reference to an object you do not own. The left hand side (LHS) assigns this reference to the instance variable name. You have now stored a reference to something you do not own, this is bad as at any future time the owner(s) of the object may relinquish ownership, the object destroyed, and you have an invalid reference in name. Lesson: *Do not store references to objects you do not own in instance variables".

On the other hand the RHS of line 9 returns a reference to an object you do own. However the LHS uses a property invocation self.name to store the reference, and that also takes ownership as it is a retain property - you now own it twice, this is bad but if a different way; unless you also relinquish ownership twice, which you probably won't do, the object will always have an owner and will live forever, commonly called a leak.

If you swap the code around:

Line  7a:     name = [[NSString alloc] initWithString:@"Hello"];
Line  8a:                          OR
Line  9b:     self.name = [NSString stringWithString: @"Hello"]; 

then it will do what you expect. The RHS of line 7a returns an object reference you own and the LHS stores it in the instance variable name which is managed by the property name.

The RHS of line 9a returns an object reference you do not own, however the LHS uses a property invocation and as the property has the retain attribute ownership is taken and the reference stored in the instance variable name is to an owned object.

In either case when the current instance (self) is destroyed as the property name has the retain attribute ownership of any object reference by the instance variable name will be relinquished.

Question 2

What is the affect of using:

@synthesize name = _name;

This just means that the property name will use an instance variable _name rather than name. In your code snippets you never declare name or _name so both are automatically declared by the @synthesize; so there is only either a name or an _name instance variable depending on the @synthesize. So the answer to Question 2 is the answer to Question 1 with every reference to the instance variable name replaced by _name.

Question 3

If I understand this question, and I'm not sure I do, it is covered by the answer to Question 1.

HTH

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top