开发者

Memory leak with objective-c on alloc

When I use Instruments to find memory leaks, a leak is detected on

Horaires *jour;     
jour= [[Horaires alloc] init]; // memory leak reported here by Instruments
self.lundi = jour;
[jour release];

and I don't know why there is a leak at this point.

Does anyone can help me? Here's the code.

// HorairesCollection.h
#import <Foundation/Foundation.h>
#import "Horaires.h"

@interface HorairesCollection : NSObject < NSCopying > {
    Horaires *lundi;
}

@property (nonatomic, retain) Horaires *lundi;
-init;
-(void)dealloc;
@end


// HorairesCollection.m
#import "HorairesCollection.h"

@implementation HorairesCollection

@synthesize lundi;

-(id)copyWithZone:(NSZone *)zone{
    HorairesCollection *another = [[HorairesCollection alloc] init];
    another.lundi = [lundi copyWithZone: zone];
    [another autorelease];
    return another;
}

-init{
    self = [super init];
    Horaires *jour;     
    jour= [[Horaires alloc] init]; // memory leak reported here by Instruments
    self.lundi = jour;
    [jour release];
    return self;
}

- (void)dealloc {
    [lundi release];
    [super dealloc];
}

@end


// Horaires.h
#import <Foundation/Foundation.h>

@interface Horaires : NSObject <NSCopying>{
    BOOL ferme;
    BOOL h24;
    NSString *h1;
}

@property (nonatomic, assign) BOOL ferme;
@property (nonatomic, assign) BOOL h24;
@property (nonatomic, retain) NSString *h1;

-init;
-(id)copyWithZone:(NSZone *)zone;
-(void)dealloc;

@end


// Horaires.m
#import "Horaires.h"
@implementation Horaires

-(BOOL) ferme {
    return ferme;
}

-(void)setFerme:(BOOL)bFerme{
    ferme = bFerme;
    if (ferme) {
        self.h1 = @"";开发者_运维知识库
        self.h24 = NO;
    }
}

-(BOOL) h24 {
    return h24;
}

-(void)setH24:(BOOL)bH24{
    h24 = bH24;
    if (h24) {
        self.h1 = @"";
        self.ferme = NO;
    }
}

-(NSString *) h1 {
    return h1;
}

-(void)setH1:(NSString *)horaire{
    [horaire retain];
    [h1 release];
    h1 = horaire;
    if (![h1 isEqualToString:@""]) {
        self.h24 = NO;
        self.ferme = NO;
    }
}

-(id)copyWithZone:(NSZone *)zone{
    Horaires *another = [[Horaires alloc] init];
    another.ferme = self.ferme;
    another.h24 = self.h24;
    another.h1 = self.h1;
    [another autorelease];
    return another;
}

-init{
    self = [super init];
    return self;
}

-(void)dealloc {
    [h1 release];
    [super dealloc];
}

@end


You've set your property to retain and you alloc and release the variable, so from what I can see the code is okay and Instruments has given you a false warning.

I think your copyWithZone: might have a leak, though. [lundi copyWithZone:] will retain a copy of lundi but you never release it. So you need an extra release, something like this:

-(id)copyWithZone:(NSZone *)zone{
    DefibHoraires *another = [[DefibHoraires alloc] init];
    Horaires* makeCopy = [lundi copyWithZone: zone];
    another.lundi = makeCopy;
    [makeCopy release];
    return another;
}

This is because copy and alloc both return retained object instances and you need to manually release them when you're finished with them. You did that correctly for your alloc'd objects but not the copy.


That init method looks ok, although it should be implemented (and typed) as

-(id)init
{
    if (self = [super init])
    {
        ...
    }
    return self;
}

or a similar pattern.

Your copyWithZone implementations are wrong, they need to return a retained object, so do not autorelease the returned value. But you need to release your copy of lundi, because you are using the retaining setter.

-(id)copyWithZone:(NSZone *)zone{
    DefibHoraires *another = [[DefibHoraires alloc] init];
    Horaires *lundiCopy = [lundi copyWithZone:zone];    
    another.lundi = lundiCopy;
    [lundiCopy release];
    return another;
}

I don't know why you return an instance of DefibHoraires here, shouldn't it be a HorairesCollection?

Maybe the wrong copyWithZone: method is responsible for the reported leak (it's a leak anyway).

One further note: It's a good defensive rule to use (copy) for NSString properties instead of (retain) to remove side effects when passing NSMutableString instead.


I don't have an answer but I do have some general comments:

  1. In copyWithZone: you should use allocWithZone: (passing the same zone as a parameter) to allocate the object you are going to return.
  2. copyWithZone: should return a retained object. Don't autorelease it.
  3. You are not supposed to use properties in init. Your init should look something like:

    -init
    {
        self = [super init];
        if (self != nil)
        {
            lundi = [[Horaires alloc] init]; // assign the ivar directly
        }
        return self;
    }
    
  4. In your copyWithZone: for HorairesCollection you have a leak. It should look like:

    -(id)copyWithZone:(NSZone *)zone{
        DefibHoraires *another = [[DefibHoraires allocWithZone: zone] init];
        another.lundi = [[lundi copyWithZone: zone] autorelease];
        return another;
    }
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜