2011-01-10 2 views
0

Когда я использую инструменты для поиска утечек памяти, утечка обнаружена наУтечка памяти с Objective-C на Alloc

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

, и я не знаю, почему происходит утечка в этой точке.

Кто-нибудь может мне помочь? Вот код.

// 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 
+0

В Horaires.m вы создаете свойство для h1, а также написанием его использование прибудет синтез. – Robin

ответ

2

Вы установили свою собственность, чтобы сохранить и вы Alloc и освободить переменную, поэтому от того, что я могу видеть, что код хорошо и инструменты дал вам ложное предупреждение.

Я думаю, что ваш copyWithZone: может иметь утечку, хотя. [lundi copyWithZone:] сохранит копию lundi, но вы никогда ее не выпустите. Так что вам нужен дополнительный релиз, что-то вроде этого:

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

Это потому, что copy и alloc возвращают сохранить экземпляры объектов, и вы должны вручную освободить их, когда вы закончите с ними. Вы сделали это правильно для объектов alloc'd, но не для копии.

+0

другой.lundi синтезирован, [lundi copyWithZone:] установлен в другой.lundi. Почему возникла утечка и как ее решить? Я новичок в объективе-c. – Grunzig

+0

Поскольку копия сохранена ... Я пересмотрел свой ответ. –

+0

[autorelease] - ошибка. copyWithZone: требуется вернуть * сохраненный * объект. – Eiko

0

Это init метод выглядит нормально, хотя она должна быть реализована (и напечатал), как

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

или аналогичная картина.

Ваши экземпляры copyWithZone ошибочны, им необходимо вернуть сохраненный объект, поэтому не возвращайте автоматически возвращаемое значение. Но вам нужно освободить свою копию lundi, потому что вы используете удерживающий сеттер.

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

Я не знаю, почему вы возвращаете экземпляр DefibHoraires здесь, она не должна быть HorairesCollection?

Возможно, неправильная копияWithZone: метод отвечает за сообщенную утечку (это утечка в любом случае). далее

Одно примечания: Это хорошее оборонительное правило использовать (copy) для NSString свойств вместо (retain), чтобы удалить побочные эффекты при прохождении NSMutableString вместо этого.

+0

О, просто * еще одна вещь *: Я обычно использую английский в своем коде и никогда не оглядывался назад. ;-) – Eiko

+0

Статический анализатор также очень хорошо разбирается в таких проблемах. – Eiko

+0

Спасибо всем. Я изменю свой код. Это не DefibHoraires, а HorairesCollection. Я изменяю код своего вопроса. – Grunzig

0

У меня нет ответа, но у меня есть некоторые общие замечания:

  1. В copyWithZone: вы должны использовать allocWithZone: (передавая ту же зону в качестве параметра), чтобы выделить объект, который вы собираетесь вернуться.
  2. copyWithZone: должен вернуть сохраненный объект. Не проверяйте его.
  3. Вы не должны использовать свойства в init. Ваш INIT должен выглядеть примерно так:

    -init 
    { 
        self = [super init]; 
        if (self != nil) 
        { 
         lundi = [[Horaires alloc] init]; // assign the ivar directly 
        } 
        return self; 
    } 
    
  4. В вашем copyWithZone: для HorairesCollection у вас есть утечка.Он должен выглядеть следующим образом:

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

Для 3., если я использую lundi вместо self.lundi, мое приложение вылетает – Grunzig

+0

@Grunzig: вы уже выпустили его где-то в другом месте. – JeremyP

Смежные вопросы