2011-12-15 4 views
1

Прежде всего, извините за количество кода. Что я делаю неправильно, управляя памятью. Я не понимаю, почему анализатор выбрасывает утечку памяти.утечка памяти в простой пример кода

@interface obj : NSObject 
{ 
    NSMutableArray *array; 
} 
@property (retain, nonatomic) NSMutableArray *array; 
@end 

@implementation obj 
@synthesize array; 

- (id)init 
{ 
    self = [super init]; 
    if (self) 
    { 
     // Initialization code here. 
     array = [[NSMutableArray alloc] init]; 
    } 

    return self; 
} 

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

@end 

int main (int argc, const char * argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    // insert code here... 
    obj *test = [[obj alloc] init]; 
    NSNumber *numero = [[NSNumber alloc] initWithFloat:3.4]; 

    NSLog(@"Número: %g \n", [numero floatValue]); 

    [test.array addObject:numero]; 

    NSLog(@"Numero de elementos: %lu", [test.array count]); 

    NSLog(@"Valor: %g", [[test.array objectAtIndex:0] floatValue]); 

    NSLog(@"Numero de elementos t2: %lu", [test.array count]); 

    numero = [NSNumber numberWithFloat:5.8]; 

    NSLog(@"Valor t2: %g", [[test.array objectAtIndex:0] floatValue]); 
    NSLog(@"Número t2: %g \n", [numero floatValue]); 

    [test.array addObject:numero];  

    NSLog(@"Valor: %g", [[test.array objectAtIndex:0] floatValue]); 

    [numero release]; **<-- Leak of memory** 
    [test release]; 
    [pool drain]; 

    return 0; 
} 

ответ

2

Легко исправить, вы забыли освободить существующее значение, прежде чем переназначать его.

// You created an instance of NSNumber here 
NSNumber *numero = [[NSNumber alloc] initWithFloat:3.4]; 

// Then you reassigned it here without releasing it first which caused the leak HERE 
numero = [NSNumber numberWithFloat:5.8]; 

[numero release]; **<-- Leak of memory** 

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

NSNumber *numero = [NSNumber numberWithFloat:3.4]; 

numero = [NSNumber numberWithFloat:5.8]; 

// Now you don't need to release it at all ;) 
//[numero release]; **<-- Leak of memory** 

Или вы можете исправить существующий пример по:

NSNumber *numero = [[NSNumber alloc] initWithFloat:3.4]; 

[numero release]; 

numero = [NSNumber numberWithFloat:5.8]; 

// Remove this one since numberWithFloat returns an autoreleased object 
//[numero release]; **<-- Leak of memory** 
+0

Спасибо за вашу помощь и большое объяснение. Я не знал, что метод humberWithFloat был автореализован. –

1

В вашем методе dealloc, попытайтесь освободить array первый, а затем вызова [super dealloc]. (Как правило, вы должны освободить свой Ивар первым, перед вызовом dealloc метода суперкласса.)

2
  1. [super dealloc]ВСЕГДА быть последним вызовом в методе dealloc.
  2. Всякий раз, когда вы назначаете переменную для ссылки, которой вы владеете (например, результат вызова alloc/init), вы должны освободить ее, прежде чем переназначить ее.

NSNumber *numero = [[NSNumber alloc] initWithFloat:3.4]; 
... 
[numero release]; //You must call release before reassigning 
numero = [NSNumber numberWithFloat:5.8]; 
... 
[numero release]; //This is bad because it is now assigned an autoreleased value 

Теперь для примера там не нужно выделять начальный numero и просто назначить его в качестве NSNumber *numero = [NSNumber numberWithFloat:3.4];, как вы делаете все остальное, то нет необходимости в каких-либо призывы освободить.

0

После добавления numero в вашем массиве вам нужно освободить numero, потому что вызовы addObject сохраняются на numero. Второе число 5.8 в порядке, потому что вы не вызываете alloc на него.

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