Reputation: 2535
I am having problem with understanding one concept of memory managment, because I am new to objective C. For instance lets say I have a class Bar and Foo.
in main function I call:
Foo *foo = [bar getFoo]; //In my bar method I return foo
[foo retain];
[foo callMethod];
[foo release];
I know this is right way to do it. But why do we have to retain it after we get it from another object, does not this mean returning object has retain count 0 ? so we have to reatin it to count 1 to use it? but if it has reatin count 0, how do we know it is still there. We can assume since it is the next line that increment retain count that the object memory wont be realocated, but what if we have multi-threading program?
Upvotes: 1
Views: 75
Reputation: 6505
The method getFoo
doesn't return an object with a 0 retain count. It returns an object with a +0 retain count which means that:
release
/autorelease
as retain
/alloc
/new
/copy
).Thus the lifetime of the object entirely depends on where and how it is retained. We don't know how long the object will be valid as any method invocation could release the object.
For example, let's consider the following code:
id anObject = [anArray objectAtIndex:0]; [anArray removeObjectAtIndex:0];
The object anObject
isn't retained any more by the array as we removed it. Therefore it may have been destructed (but maybe it wasn't because it is still used somewhere else).
Generally, when getting an object from a method (other that alloc
, copy
, new
or retain
), we can assume that:
So we know the object foo
is valid until we return from the current method/function or we invoke a method/function that alter the state of the object bar
, whichever comes first. After that, it may have been destructed.
So in your case, you can safely omit the retain
/release
pair.
However, it is very difficult to guaranty that an object doesn't get released unless we know the implementation of every method we invoke. Therefore, retaining (then releasing) every single object we get is the safer approach and that's what the compiler will do when you enable ARC (Automatic Reference Counting).
But that would require you to write a lot of retain
/release
and your code would become difficult to read, understand and maintain. Moreover, the more code you write, the more bugs you get (unless you never write bugs).
In conclusion, you don't need to retain an object unless you have a reason to suspect it could vanish otherwise.
Upvotes: 0
Reputation: 122391
When an class method returns an object, it will autorelease
it so you don't have to bother; typically:
- (Foo *)getFoo
{
return [[_foo retain] autorelease];
}
If you are only using foo
for the lifetime of the calling method you don't need to retain
it, as it won't be autorelease
d until next time through the run loop, so your code should actually be:
Foo *foo = [bar getFoo]; //In my bar method I return foo
[foo callMethod];
If, however, you want to hold foo
for a while, outside the scope of the calling method, you need to retain
it and then release
it sometime later.
One more thing; the convention for getter method names is simply "name", so your setter should be setFoo
and your getter would be foo
. Keeping to the naming conventions is a good idea as it lets you know what a method does, in say 7 months time, and tools like static analysis understand the conventions.
Upvotes: 3