I am developing an objective C framework which will ship as a static library at the end. But when I integrate that library to an actual application (by adding the static library) in the leaks tools I see some memory leaks present.
Here is an example scenario.
@implementation Test
@synthesize testNumber
+(Test) createTestInstance {
Test *test = [[Test alloc] init];
test.testNumber = [[NSDecimerNumber alloc] initWithInt:1];
return test;
}
-(void) dealloc {
[testNumber release];
}
@end
Although I release testNumber variable in dealloc I see a memory leak in Leaks tool at alloc position. What can be the issue here?
Also as this is a library provided for user to invoke, is it a best practice to release those variable from the library code?
Thank You
I see two problems here. If testNumber
is a retain property, you are overretaining it with this statement:
test.testNumber = [[NSDecimerNumber alloc] initWithInt:1];
Both alloc-init and the property accessor are retaining the object. Therefore, it should be:
test.testNumber = [[[NSDecimerNumber alloc] initWithInt:1] autorelease];
There is no need to mention that you still need to release testNumber
in the dealloc
method.
Also, I understand createTestInstance
is a convenience constructor to create Test
objects and it should return an autoreleased object according to the Object Ownership Policy (only methods with names that start with “alloc”, “new”, “copy”, or “mutableCopy” return an object you own):
+ (id)createTestInstance {
Test *test = [[[self alloc] init] autorelease];
test.testNumber = [[[NSDecimerNumber alloc] initWithInt:1] autorelease];
return test;
}
Finally, as suggested by @Josh Caswell, convenience constructors should return id
instead of the specific class. From The Objective-C Programming Language:
The return type of convenience constructors is id for the same reason it is id for initializer methods, as discussed in “Constraints and Conventions.”
Also, they should use self
instead of the hard-coded class name to alloc-init the instance in order to handle subclassing properly (self
here refers to the class object itself since this is a class method).