One of the special enhancements Objective C adds to basic C/C++ is the ability to declare and use properties with a simple and straightforward usage. To new comers or even veteran programmers used to properties in C# or Java this is a very nice concept that saves a lot of time while keeping the code readable.
However, as with any platform/framework, everything has its quirks and it takes time to learn them. One of the things I got wrong, or better, that I assumed incorrectly when learning ObjC, was that the @synthesize did all the work magically. Since it automatically retains, assigns or copies when you assign an object, it was a fair assumption that when the object’s dealloc was called it would also release the property’s object according to the defined settings.
It turns out I learned quite a while ago that this wasn’t the case, but meanwhile, it had already cause a lot of pain and debug sessions. One of the first places I first realized the problem was when used the pretty much standard delegation pattern:
@property (retain) id delegate;
At that time, my decision was to use assign since I always check for nil before performing any selector on the delegate, and in that project it did make sense. However, each time I was faced with the problem again I always thought, I must be doing something wrong, why do I always need to release all my properties? Today I decided to check and the answer is pretty clear albeit buried away in the documentation. You see read it at Apple’s online docs.
While this is a minor inconvenience, all you have to do is set all property to nil when you dealloc your object, self.prop = nil; will do nicely. However, I’m lazy and I was trying to accomplish this automatically, I’ve imagined 2 solutions that required me to use reflection to get all the properties on an object and set them to nil. When doing some research on the reflection subject I found exactly what I wanted in a form of a NSObject category which was one of the solutions I was trying to implement. The second one would be to override the NSObject and make the dealloc call do this, but that would force me to replace every custom class I had so it wasn’t an option for implementers of classes like UITableViewCell. Anyway, if anyone wants it you can check it at Vicent Gable’s Blog- Automatically Freeing Every @property blog post, although I must advise that there will be a performance penalty for being lazy, as always 😛
Tags: iPhone, objectivec, quirks, sdk
Good post. 1 remark. It is ok to send a message to nil, so no need to check nil when sending a message. What is dangerous is to send messages to garbage pointers
Ok, next thing you’ll need to learn is, that usually you don’t retain your delegates
This is because usually you’re delegate is retaining the class itself (think of a uitableviewcontroller retaining its uitableview while being its delegate) and when the class retains its delegate back you got a classic retain-cycle. So none of your objects will be dealloced.
The other thing which is a good practice is, not use setters in your init and dealloc. This becomes more important when you use KVO. Setters will always notify your observers. This is something you might not want when your object is just about to be released.