Object with retain count 0 doesn't get released - objective-c

Why is my object in the following leak trace doesn't get released?
The trace says its reference count is 0, so why doesn't it get released?
The object is a custom class that derives directly from NSObject. all I do with it is alloc it, init it, copy some strings/numbers from it, and send release, but still its considered a leak and doesn't get deallocated. I see it under allocations in instruments as 'living' so its really not deallocated. I create hundreds of these objects, so I cannot allow them to live.
How can I make this object get deallocated? why isn't it deallocated in the first place?

Well, it looks like you forgot to call [super dealloc] in your -dealloc method. We've all done that. :)
So the object is getting the dealloc call as you would expect, but isn't actually being deallocated.

Related

Dealloc method isn't called when i release perticular object

I have created an object using alloc/init method, and after I release it -dealloc should be called immediately as per documentation. I set a breakpoint on -dealloc method but it isn't hit, and my -dealloc method is not called.
Please tell me what is the reason behind that, and what is use of dealloc method in objective c ?
The -dealloc method is not always called when you expect it to be called. The runtime might also have issued a -retain on your object for internal reasons.
It's also possible that you have (directly or indirectly) caused an extra -retain to be issued. If the retains/allocs and releases are not balanced, you'll never see -dealloc called. It helps to turn on the Static Analyzer, to make sure your calls balance.
Just follow the memory management rules, don't second guess the runtime, and let the memory management system do its job.
The answers to When does dealloc method call? may help you understand what you're seeing.
because it still has reference. that means its reference count not reached to zero. i don't know your code, where it is referencing. but it is not calling that means somehow still it has reference. it may be because of strong relationship or parent-child relationship
all Objective-C objects are allocated on the heap, so they must
therefore be deallocated somewhere if you are not to run out of
resources.
This gave way to the reference counting method, which is still used
today: each object keeps count of any references held to it. If you
receive an object and you want to keep it, you retain that object,
incrementing its reference count. When you are done with it, you
release it, which decrements its reference count. Once that count
reaches zero, it is inferred that no one is referencing the object and
it is automatically deallocated using the -dealloc method.
Additionally, an object could be told to “release at some point in the
(hopefully) near future” using autorelease pools. The idea is that
somewhere on the stack (typically at the start of a thread or while
responding to input events) an autorelease pool is created and pushed
onto a stack. Any object can then be sent an -autorelease message, and
it is assigned to that pool.
When the pool object is deallocated, it simply sends a -release
message to all its assigned objects. That way, any objects that are no
longer used (i.e. they haven’t been explicitly retained) are then
deallocated.
The dealloc is called (at more cases) whenever your object is released. You can't directly call this method.
#interface myViewController:UIViewController
{
NSString *myStr;
}
#end
Here the dealloc method in the #implementation of myViewController will be called (at most cases) when the myViewController object is released, not when myStr is released.
Although you don't have to use if you ARC.

What happens if your mark an autorelease object as autorelease

My question may sound stupid an all, but I like to know what happens if I mark an autoreleased object as autorelease. Will it be released twice? Or nothing happens? For example:
Obj * obj = [[Obj create] autorelease];
Let's say [Obj create] returns an autoreleased object.
If I add another autorelease, what happens then?
Yes, sending autorelease twice will release the object twice. If your create method returns an autoreleased object and you send another autorelease message to it, your app will crash, because you'll be releasing a deallocated object.
Having said that, why don't you use the new Automatic Reference Counting (ARC)? You don't have to worry about (auto)releasing objects anymore.
You use the Class Method(+), you should not to care the memory. People use Class Method one reason is that it can return an autorelease object. If you release or autorelease the object which the Class Method returns, it will crash.

Confusion on dealloc calls

I have a basic question here.
I know that dealloc will be called when the object's reference count becomes zero,and dealloc releases all the resources hold by the object or frees memory, right?
The object reference count becomes zero if we send release message to that object right?.
Lets consider the following object with its property created as,
#property (retain) NSString* myString;//reference count 1
and dealloc
[myString release];//reference count 0
[super dealloc];
I am not releasing the myString object any where except in dealloc.
My question is who is making myString object reference count to zero so that dealloc will be called?
Please clarify my doubt.
Anything that maintains ownership of the object is responsible for releasing it. For example if the code you posted is the only thing that maintains ownership of the NSString stored in myString then when you call release the reference count will be decreased and the object will likely be deallocated (String literals are different). Now if you passed myString around or something else requested myString and retains it then that code is also responsible for releasing it which may be before or after you release it in the dealloc method.
I recommend referring to the documentation for reinforcing this concept.
Let's say your property myString is within your class MyClass. Each instance of your class is created and (presumably!) released. When that instance is [released], your dealloc method of MyClass is called. Your dealloc in turn calls release on your properties, which in turn invokes their dealloc, and so on until you reach the 'bottom' of this stack of objects using objects.
Your object will only be free'ed if the retain/release pairs match up. If you follow the cocoa memory management (see apple docs - advances memory management programming guide)
rules, you are the only 'owner' at that point - and running dealloc zap's the last reference away - free'ing the object.

Retain count and dealloc in iPhone

I want to ask about the iPhone application and objective C question. In the implementation program, there are function called 'dealloc', does this function only be called one time by the application?
For example, if I alloc a object and retain it 2 times, the retains count is 2 and I never use 'release' in the program, unless in the dealloc. Will the object be removed from the memory, or the objective will be removed from the memory. Thank you.
In the implementation program, there are function called 'dealloc', does this function only be called one time by the application?
Yes. -dealloc destroys the object. Trying to send any message to it again, including -dealloc is an error.
if I alloc a object and retain it 2 times, the retains count is 2
Careful. The retain count is at least 3. Other things than your code might retain the object. It's better not to worry to much about retain counts and only think in terms of ownership.
Each alloc, new, copy or retain is an claim of ownership. The object's dealloc method will only be called when all claims of ownership have been relinquished. A claim of ownership is relinquished by sending -release. So if you never release an object except in its own dealloc, you'll never release it.
dealloc is called once by the system when the object is destroyed (when its reference count reaches 0). If you have member variables in your class that you alloc in your init function, you must release them in your dealloc function.
If you give someone a pointer to one of those member objects and they retain it, the member could survive the release in your dealloc, but by sending a retain message they are taking responsibility for sending a release message later, ensuring its eventual destruction.

Memory Management Question in Objective C

I have a tableviewcontroller where I populate some data from a sqlite db and for each row, I download a file from a http server and cache it locally. I cache it only when the "detailsview" is opened. And the detailsview responds back to this table through a delegate after the file download is complete.
But, when this tableview itself is popped out of the navicontroller., the call to delegate fails with a EXEC_BAD_ACCESS
I called [_delegate retain] in the setDelegate of the details view and everything works fine, but I'm not sure whether this will leak memory...
Could anyone advise?
Your delegate is getting released prematurely, and sending a message to an invalid object will call EXEC_BAD_ACCESS. Retaining it will fix the problem, but in general it's good practice to not have an object retain its delegate, as there is the potential for retain cycles, so you might need to rethink your structure. If you're releasing your delegate when the view is dealloc'ed, you need to remove it unless you're also retaining the delegate in setDelegate:.
Generally, delegates are not retained to avoid retain cycles. If the delegate may be released before you, then it is the responsibility of the delegate to clear your reference before it is finished being deallocated (eg in its dealloc).
However, if any property is set to "retain" or "copy", then you would retain/copy it in the setter (or use #synthesized setters which will do it for you), and release it in dealloc to avoid leaking. As said above though, that may lead to a retain cycle so that neither object ever gets deallocated.
I would suggest you turn on some memory debugging with environment variables NSZombieEnabled and NSAutoreleaseFreedObjectCheckEnabled and see if it tells you which object is being over released.