在iOS中,不要在init方法和dealloc方法中使用setter、getter方法
因为如果子类重写了父类的访问器方法时,可能会导致内存泄漏(例如子类的setter方法,赋给特性另外一个值,在delloc方法中使用self.var=nil时,调用子类的setter方法,导致该值不能被释放,从而发生内存泄漏)。
#import <Foundation/Foundation.h>
enum { UseItTheRightWay = false
//-OR- false
};
@interface MONObjectA : NSObject
{
NSMutableArray * array;
}
@property (nonatomic, retain) NSArray * array;
@end
@implementation MONObjectA
@synthesize array;
- (id)init
{
self = [super init];
if (0 != self) {
NSLog(@"%s, %@",__PRETTY_FUNCTION__, self);
if (UseItTheRightWay) {
array = [NSMutableArray new];
}
else {
self.array = [NSMutableArray array];
}
}
return self;
}
- (void)dealloc
{
NSLog(@"%s, %@",__PRETTY_FUNCTION__, self);
if (UseItTheRightWay) {
[array release], array = nil;
}
else {
self.array = nil;
}
[super dealloc];
}
@end
@interface MONObjectB : MONObjectA
{
NSMutableSet * set;
}
@end
@implementation MONObjectB
- (id)init
{
self = [super init];
if (0 != self) {
NSLog(@"%s, %@",__PRETTY_FUNCTION__, self);
set = [NSMutableSet new];
}
return self;
}
- (void)dealloc
{
NSLog(@"%s, %@",__PRETTY_FUNCTION__, self);
[set release], set = nil;
[super dealloc];
}
- (void)setArray:(NSArray *)arg
{
NSLog(@"%s, %@",__PRETTY_FUNCTION__, self);
NSMutableSet * tmp = arg ? [[NSMutableSet alloc] initWithArray:arg] : nil;
[super setArray:arg];
[set release];
set = tmp;
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[[MONObjectB new] release];
/* the tool must be named 'Props' for this to work as expected, or you can just change 'Props' to the executable's name */
// system("malloc_history");
system("leaks memory_leak");
[pool drain];
return 0;
}
在MONObjectB释放时调用父类的delloc方法,该方法会调用子类setArray方法,将set赋给实例变量array时,set的引用计数为1,在MONObjectB释放后,set没有被释放,从而导致内存泄漏。 (http://stackoverflow.com/questions/5932677/initializing-a-property-dot-notation/5932733#5932733)