Objective-C retain counts in dealloc - objective-c

I'm seeing something fairly strange here, I've got breakpoints set in various dealloc methods in my app, and on inspection, the retain counts of the object self varies from 1 to 0. When dealloc is called, will the retain count of the object be set to 0 already?
I'm using print (int) [self retainCount] in the console to test this.
The 0's seem to only appear in the dealloc of my NSOperation's that are being run in an NSOperationQueue.
Any idea why this is?

The retain count of your object doesn’t matter in -dealloc. For practical purposes, it’s undefined.
The normal implementation of reference counting uses an external reference count for values greater than zero – see NSIncrementExtraRefCount() and NSDecrementExtraRefCountWasZero(). When the extraRefCount count is zero, the refCount is one. When NSDecrementExtraRefCountWasZero() is called and the extraRefCount is already zero, it returns YES and -dealloc is called. Except when dealing with the return value of NSDecrementExtraRefCountWasZero() there is no way to distinguish a refCount of one from a refCount of zero.
That NSOperation gets a zero refCount suggests it’s not using the normal mechanism.

I'm not quite sure how objective-c handles this but if the dealloc method is being called, it means the retain count has hit 0 so object should be released from memory. There's no other way around it, if your object has a retainCount of 2 and you call [obj release] once, your dealloc method will never be called - so if your breakpoints are being hit and written to the Log then you can be sure that the object is on its way to being destroyed
Remember that your object will subclass NSObject so you should be putting a [super dealloc] call in your dealloc method too.

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.

Which increases the retain count: alloc or init?

When we need create an object and take ownership of it we write
NSObject *someObject = [[NSObject alloc] init];
After that someObject's retain count will be equal to 1. Which method increases the count, alloc or init, and where in Apple's docs is this behavior described?
After that someObject's retainCounter will be equal 1. Question is
which method increases retainCounter alloc or init and there in Apple
docs this behavior is described?
"Neither", "Both", or "One or the Other" would all be correct answers. A better answer would be "it is an implementation detail and you need to focus on the general, non implementation dependent rule".
First, ditch the notion of absolute retain counts. It is a useless way to think of this.
+alloc returns an object with a +1 retain count. Whatever is returned by +alloc must be -released somewhere. Wether or not the actual retain count is 1 or not is entirely an implementation detail and it often is not 1 for many of Apple's classes.
-init consumes the retain count of the messaged object and produces an object of retain count +1 (not 1, but "plus 1"); the result returned from init must be released to be managed correctly.
More often than not, init simply calls return self; without internally manipulating the retain count. This preserves the above rule.
Sometimes it doesn't, though, which is why you always have to have self = [super init] (checking the return value, of course) in your initializers and why you should never do something like Foo *f = [Foo alloc]; [f init];.
The alloc method does the actual allocation therefore will generally* increase the retain count. The init is responsible for initializing the object after the allocation.
*There are exceptions to this in several foundation classes as well as 3rd party code (class clusters for example) but you are always responsible for calling release/autorelease after a call to alloc in manual memory management
Well, so it's kinda complicated. For almost all cases, +alloc increments the retain count, and -init does nothing to the retain count.
But occasionally, -init will want to return a pre-existing object rather than initializing the blank one alloc passed it. (NSNumber does this, for example.) In that case, -init would release self, then return a new object with a +1 retain count.
In the ARC documentation, they say that -init is a method which "consumes" its recipient, and returns a retained object. Often, that just means init does nothing to the retain count. But sometimes, -init is actually doing some retaining.
If this is confusing to you, don't worry about it.
As I said, +alloc is the one doing the retaining. -init is guaranteed to return a retained object, but doesn't itself do any retaining in most cases.

Object with retain count 0 doesn't get released

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.

Suicide: Objective-C objects calling their own -dealloc methods on themselves

Is it good practice for an object in Objective-C to commit suicide? That is, for an object to declare [self dealloc] where -dealloc permits an orderly wind down as usual? What are the principal risks?
As it happens I have a specific example, a custom timer object that extends NSObject and comprises an NSTimer instance and an NSUInteger which is set to limit the number of times the timer fires. When time is up the object tells the timer to -invalidate and then commits suicide by calling its -dealloc method. As this is automatic we have no worries about having to track the object or crucially knowing when is the correct moment to deallocate it.
For a more detailed explanation see my post over here.
You shouldn't be calling -dealloc. Instead call [self release] so the reference count goes to 0 and let the system call -dealloc.
Is it good practice for an object in Objective-C to commit suicide? That is, for an object to declare [self dealloc] where -dealloc permits an orderly wind down as usual? What are the principal risks?
No.
The only time you should ever write a call to dealloc is to send dealloc to the super object in the dealloc method of one of your classes. No exceptions.
If you try to send dealloc to an object at any other time, you risk leaving other objects with dangling pointers. Don't do it.
Should you ever send release to self? That is a different matter, but you should still follow the Memory Management Rules. If you have sent retain to self, then at some point you will need to send release to self. There is one exception which is in init, if initialisation fails you have to release self and return nil (I guess you could claim that alloc has sent retain to self).

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.