If I do a refcount or retainCount for self.navigationItem.rightBarButtonItem it shows that it has 3 references!
Why? Should I care?
Why do I have to write autorelease there?
What if I don't?
When do I know I should call autorelease?
By using autorelease, you are making the object to be placed ion autorelease pool.
Yes, if you are not doing memory management on your own and
NO, if you are doing memory management on your own.
No compulsion to write. Please refer the above two questions.
Please refer the above questions.
It depends on you. Please refer the above questions.
You put it in so simple terms but I'm really confused about the fact that while I'm allocating one single object and giving it away, it should(?) have just one reference, but it has 3.
How am I sure that if I don't write autorelease it will get released by the object who owns it?
Because the fact that the original had an "autorelease" makes me doubt of the fact that, while I can be perfectly fine managing my own memory, the API still needs that I make a call to autorelease every now and then.
I mean, to me and my code, putting an autorelease there is exactly the same. I don't own the object, the API does, the API should release it.
Is it exactly the same for the API?
Will it make the appropriate release calls?
In this case, yes, I believe you should autorelease. You called alloc/init on the object, so you need to release it somewhere. The easiest way to do that is to call autorelease, so that it gets released at the end of the current event.
Don't worry about who else retained it, and why - that's their business.
Here's another, also correct, way to do what you're doing:
If I do a refcount or retainCount for self.navigationItem.rightBarButtonItem it shows that it has 3 references!
Why? Should I care?
In general, you should not look at object retainCounts... They are often misleading. If you are using any framework classes, they will have retains all over your stuff (as you discovered). Don't worry about it. Remember, the goal isn't to make sure the retainCount is zero - the goal is to make sure all your retains & releases are balanced. myfoo = [[foo alloc] init] does an implicit retain, so it must be balanced with a release or autorelease.
I used to use autorelease all the time because I didn't really understand what I was doing, but I'm trying to break the habit and use it only when absolutely necessary. You should prefer the method that Smasher mentioned. Alloc/init, then use the object or assign it somewhere else, then release. Clean and simple, immediately obvious that the retains & releases are balanced.
If you have any doubts about your code, I recommend investigating the Clang Static Analyzer. It runs over your code and can identify problematic memory management areas for you in a way that the normal compiler and even the Leaks tool can't.
Common sense dictated to me that since I wasn't retaining the object I just allocated (and I was giving it directly to another object), the retain count wouldn't increase.
Does this means that if I do [obj setSomething:[[OtherObj alloc] init]; it will automatically become a leak? If it is so, why the compiler doesn't signal a warning here?
So the rule is that every time I do "alloc", the retain count increases 1 and I am the one responsible to decrease it?
Edit:
If that is the rule, isn't there a way to stop the language from doing this? It will make the code really messy if I can't do something like:
And what if the property is set to assign instead of retain? When I do "release" I will render the allocated memory unusable?
Must I check for every property if its set to assign or retain every time I use it?
Common sense dictated to me that since I wasn't retaining the object I just allocated (and I was giving it directly to another object), the retain count wouldn't increase.
Does this means that if I do [obj setSomething:[[OtherObj alloc] init]; it will automatically become a leak? If it is so, why the compiler doesn't signal a warning here?
So the rule is that every time I do "alloc", the retain count increases 1 and I am the one responsible to decrease it?
Edit:
If that is the rule, isn't there a way to stop the language from doing this? It will make the code really messy if I can't do something like:
And what if the property is set to assign instead of retain? When I do "release" I will render the allocated memory unusable?
Must I check for every property if its set to assign or retain every time I use it?
You created it, you're making sure it gets released. AFTER the other object has a chance to retain it if needed. Just make sure that myObj DOES retain it if needed.
Also, the compiler can't give a warning because it doesn't know what [myObj setThis:] is going to do.
And what if the property is set to assign instead of retain? When I do "release" I will render the allocated memory unusable?
Must I check for every property if its set to assign or retain every time I use it?
Nope. That's not your job. Your job is to balance your own retains and releases. (Of course, if you wrote the class that's getting the property, you're responsible for making it sure it works correctly.)
Release does not necessarily deallocate the object - only if its retain count drops to zero.
If you alloc an object, then assign it to a property of another class, you can go ahead and release it when you're done with it. It's up to the other class to have retained it (if it needs to). You shouldn't worry about it. Remember, as long as there's at least one retain on it, the object will not go away.
Since you never sent any of those objects an autorelease message, they will NOT be released when the pool drains. You leaked all three objects.
You should use [myOwnPool drain] btw unless you know for sure you will never reuse any of that code in Mac OS with garbage collection. On iPhone, release & drain are equivalent though... for now anyway.