How to use Objective C properties Properly
In programming for iOS devices, many many people get properties wrong. It is true, there are many ways to use them.
The retain property is probably the best example I can think of. Some objects when alloc’d and init’d, create a retained object. Some other + functions create autorelease objects in the iOS library. I still have problems with these at times, due to the learning curve, and finding other peoples library’s do not follow the same conventions or template that the iOS libraries do.
#import <Foundation/Foundation.h> @interface Properties : NSObject { NSMutableArray *myArray; //optional, properties now create the class object from the synthesize statement in xcode 4 and later. } @property (nonatomic, retain) NSMutableArray *myArray; @end #import "Properties.h" @implementation Properties @synthesize myArray; -(id)init { self = [super init]; if (self) { //here we assign the class object myArray the new alloc/init'd instance. This alloc/init'd instance comes with a retain value of 1 myArray = [[NSMutableArray alloc] init]; } return self; } -(void)dealloc { //here we use the accessors to release the contents. self.myArray = nil; [super dealloc]; } @end
And that my friends is how to use a retain property. If you set it = to anything else, use the class object if what is returned is already retained (mutablecopy, copy, alloc/init). If what you use is autoreleased (+ methods), use the self.myArray to obtain the object and set a retain value on it.
I realize I don’t show assign for objects or others. Assigns you can always use the accessor methods, you must retain or release objects as needed with assigns and watch them just as tho you were using a class object.
If your App Delegate has your music, sound effects, graphics, opengl context etc retained. All subclasses (main menu, game, prefs etc) should only reference those retained objects with an assign.
Specifying autorelease;
You can change a retained object into an autorelease object. Once all objects no longer retain it, it is dealloc’d.
1. Do not add an object to a autorelease pool twice.
a. Any object that comes from foundation which has a +shared by it, returns an autoreleased object. Read the documentation to ensure this is the case. Adding such an object to autorelease pool will introduce bugs and cause untraceable crashes.
b. For libraries made by other people, double check their code if its available, sometimes people do not return an autorelease object for their +shared methods.
2. Do not set a property that is retained, self.myarray = to a [[NSArray allc] init] retain]; this will result in improper retain counts. Count those retains, one by the property, one from alloc/init, and an additional one at the end with retain. 3 retains there.
I hope this helps you out, always use leak detector AND analyzer to help flush out bugs introduced using properties, and your retain counts. Hold down on the Run button, and you will get profile and analyze. Run analyzer first to fix the code problems directly, and then use profiler to get extra retain bugs you missed.









