Override "release" or "dealloc" - objective-c

Which is the best method
Override "release" or "dealloc" method in objective c?
why?

Under non-ARC, 99% of the cases you should not override the release method.
I have seen only 1 case that the need to override the release method - a kind of singleton, which forces the class have really 1 single instance no matter how many times you call alloc.
That way override not only the release method, but also allowWithZone:, retain, 'retainCount`, etc. (It is actually not common to implement that kind of singleton)

Which is the best method? Override the release or the dealloc method?
- dealloc, definitely. You should never override - release.
Why?
One, because release does a bunch of internal stuff. Two, because if release is called, it does not mean that the object is deallocated.
So you would release your ivars or null your properties by accident. And who wants an ugly segfault when we can have worldpeace instead?
If an object is really deallocated, - dealloc will be called.

If you are not using ARC, you should override the -[MyObject dealloc] dealloc method to release all retained objects inside your object. I have never found a case where I needed to override the release method.
If you are using ARC, you can usually avoid overriding the -dealloc method at all, unless you are using anything that ARC won't free up like a sqlite pointer or something.

dont override either for anything not relating to memory management - you dont when and if those methods even get called.
exceptions for when you should dealloc:
removing KVO / notification center observer
deallocating manually allocated memory (arc) / release your ivars (non-arc)

Related

overriding the dealloc method in objective-c

Can someone tell me what would actually happen if you override the dealloc method in Objective-C? As in would it crash or would it just start leaking memory all over the place. I've been wondering what would happen and why it is necessary to prevent the programmer from using dealloc directly.
And in what case would you had to do something like this?
EDIT: Sorry guys for not being clear. I was mainly talking in terms or ARC type coding.
Overriding -dealloc is an extremely common thing to do in non-ARC code. In fact, you'd be hard-pressed to find a class that doesn't override it.
The key thing to remember, though, is that every single override of -dealloc always ends with a call to [super dealloc].
Of course, in ARC code, overriding -dealloc is far less common. And if you do override it, you don't call [super dealloc], because the compiler will insert that for you. But remember, this is only true under ARC.
Before ARC overriding the dealloc method was very common, you were releasing the ivars the deallocated instance owned. Now, with ARC, is less common, however, you may have to do it in some special cases, like when you de-register an instance from observing with NSNotificationCenter.
The rule you talk about was not to call dealloc directly (not override), that would have usually led to a crash since you were bypassing Cocoa's internal reference counting system.
Edit: Based on your edit, if you call [super dealloc] under ARC, you'll get a compile time error. And if there was no error, it would have probably lead to duplicating the dealloc call, which would have made your program crash.

What kind of property should be set to nil in dealloc?

I'm using ARC. Will ARC automatically release all the properties in dealloc? Is it necessary to manual set all public properties and private field to nil? Are there any good pattern to follow?
Under ARC, the pattern is... don't do anything in dealloc, or even implement it. ARC takes care of your properties and instance variables for you.
The only exception is that dealloc is a good place to unregister for notifications, if your object has registered for any.
Good question. When using ARC the compiler will implement a dealloc method for you and will handle implicitly the release of your instance variables and properties.
You may still need a custom -dealloc if your class needs to do anything other than releasing memory (e.g unregister for notifications like jrturton mentioned).
You can get a good grasp of what's you need to consider when transitioning to ARC in those Apple official notes.

Objective C: #property(retain) doesn't call retain?

I was trying to track a strage memory allocation bug so I overrode the retain and release methods of my class. I noticed that when assigning an instance of this class to a property of another, the retain count of the object increased, but my redefined retain was never called.
How can this be possible? Are (retain) properties retaining the object without calling retain?
In my machine, the overridden retain was called. (I'm using 10.6.4. I checked this both on GCC 4.2.1 and clang 1.5.)
Could you post your code?
Internally, the synthesized setter for a retain property uses objc_setProperty, the source code of which is available here.
As you see, eventually it calls [newObject retain] when the property uses retain.
Is garbage collection turned on? I don't believe retain is called under GC.
if you don't use self (self.yourproperty), it won't increase the retain count.
I wouldn't be surprised if synthesized properties would modify the retain count without calling retain or release.

Objective-C Delegate Pointers

If we write the following code:
ExplorerAppDelegate * appDelegate = (ExplorerAppDelegate *)[[UIApplication sharedApplication] delegate];
This makes a reference to the original delegate pointer, but:
Does it increase the reference count?
Do we have to explicitly call as [ExplorerAppDelegate retain] right after, or not at all?
What's happening, exactly?
After we've used this, we should also do a [ExplorerAppDelegate release] in the dealloc method, right?
No, it does not increase the retain count.
The convention in Objective-C is that objects you are given should be memory managed by yourself - but in the case of obtaining a shared common resource like the app delegate, the memory is maintained elsewhere and of course (with this being the app delegate) you know that it will always be "alive" as long as your class is... so there is no need to retain the reference.
In most uses of delegates, instead of fetching a delegate you are given one, and that reference is not retained either. In that case whoever gave you the delegate is also responsive for clearing out the delegate link before the delegate is released.
The reason you don't want to generally retain delegate references is that it can prevent some objects from being deallocated, for instance if one class is a delegate of a class that ues the other class as a delegate.
The reference count will not be increased
You should retain it if you want to be sure that it isn't deallocated while you have a pointer to it
You should only release it if you retained it
So basically, if you're only using the object in a single function, you probably don't need retain or release it. If it exists when you get it, then it's (probably) not going to be deallocated by the end of the function. If you're keeping it around, in an ivar (member variable) for example, then you should retain it and release it later.
See the "Weak References to Objects" in Memory Management Programming Guide for Cocoa for the official answer. Pointers to delegates are one of the possible exception cases to the memory management rules.

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.