目标c内存泄漏

时间:2010-07-28 05:09:15

标签: iphone objective-c memory-management memory-leaks static-analysis

以下两种方法可返回自定义四个对象的字典。它们将字符串,浮点数和BOOL数组放入Chemical对象中,然后从数组中构建字典。我对整个内存管理游戏都足够新,当我拥有某些东西以及何时发布它时,我并不总是确定。我正在制作各种各样的琴弦。

事情就是这样:静态分析器看到第一种方法- (id)generateChlorineDictionary没有问题,但是说第二种方法- (id)generateCYADictionary有泄漏。它表示它从NSMutableArray *cyaGranulesArray...开始,然后转到NSDictionary *cyaDictionary...,最后转到return cyaDictionary声明。

以下是两种方法;抱歉他们太久了!


编辑:将名称从generateChlorineDictionary更改为newChlorineDictionary
      删除了返回后发生的版本

- (id)newChlorineDictionary {
// Sets up the array for the Bleach key
    NSMutableArray *bleachArray = [[NSMutableArray alloc] init]; 
    NSArray *bleachConcentrationArray = [[NSArray alloc] initWithObjects:@"6%", @"10%", @"12%", nil];
    float bleachConstantArray[] = {0.0021400, 0.0012840, 0.0010700};
    for (int i=0; i<3; i++) {
        Chemical *bleachChemical = [[Chemical alloc] initWithChemical:@"Bleach" 
                                                andConcentration:[bleachConcentrationArray objectAtIndex:i] 
                                                     andConstant:bleachConstantArray[i] 
                                                     andIsLiquid:YES];
        [bleachArray addObject:bleachChemical];
        NSLog(@"bleachChemical: chemName = %@, chemConcentration = %@, chemConstant = %1.6f, chemIsLiquid = %d", bleachChemical.chemName, bleachChemical.chemConcentration, bleachChemical.chemConstant, bleachChemical.chemIsLiquid);
        [bleachChemical release];
    }
    bleachConcentrationArray = nil;
// Sets up the array for the Trichlor key   
    NSMutableArray *trichlorArray = [[NSMutableArray alloc] init];
    Chemical *trichlorChemical = [[Chemical alloc] initWithChemical:@"Trichlor" 
                                            andConcentration:@"90%" 
                                                 andConstant:0.0001480
                                                 andIsLiquid:NO];
    [trichlorArray addObject:trichlorChemical];
    NSLog(@"trichlorChemical: chemName = %@, chemConcentration = %@, chemConstant = %1.6f, chemIsLiquid = %d", trichlorChemical.chemName, trichlorChemical.chemConcentration, trichlorChemical.chemConstant, trichlorChemical.chemIsLiquid);
    [trichlorChemical release];
// Sets up the array for the Dichlor key
    NSMutableArray *dichlorArray = [[NSMutableArray alloc] init]; 
    NSArray *dichlorConcentrationArray = [[NSArray alloc] initWithObjects:@"56%", @"62%", nil];
    float dichlorConstantArray[] = {0.0002400, 0.0002168};
    for (int i=0; i<2; i++) {
        Chemical *dichlorChemical = [[Chemical alloc] initWithChemical:@"Dichlor" 
                                                andConcentration:[dichlorConcentrationArray objectAtIndex:i] 
                                                     andConstant:dichlorConstantArray[i] 
                                                     andIsLiquid:NO];
        [dichlorArray addObject:dichlorChemical];
        NSLog(@"dichlorChemical: chemName = %@, chemConcentration = %@, chemConstant = %1.6f, chemIsLiquid = %d", dichlorChemical.chemName, dichlorChemical.chemConcentration, dichlorChemical.chemConstant, dichlorChemical.chemIsLiquid);
        [dichlorChemical release];
    }
    dichlorConcentrationArray = nil;
// Sets up the array for the Cal Hypo key
    NSMutableArray *calHypoArray = [[NSMutableArray alloc] init]; 
    NSArray *calHypoConcentrationArray = [[NSArray alloc] initWithObjects:@"48%", @"53%", @"65", @"73", nil];
    float calHypoConstantArray[] = {0.0002817, 0.0002551, 0.0002080, 0.0001852};
    for (int i=0; i<2; i++) {
        Chemical *calHypoChemical = [[Chemical alloc] initWithChemical:@"Cal Hypo" 
                                                andConcentration:[calHypoConcentrationArray objectAtIndex:i] 
                                                     andConstant:calHypoConstantArray[i] 
                                                     andIsLiquid:NO];
        [calHypoArray addObject:calHypoChemical];
        NSLog(@"calHypoChemical: chemName = %@, chemConcentration = %@, chemConstant = %1.6f, chemIsLiquid = %d", calHypoChemical.chemName, calHypoChemical.chemConcentration, calHypoChemical.chemConstant, calHypoChemical.chemIsLiquid);
        [calHypoChemical release];
    }
    calHypoConcentrationArray = nil;
// Sets up the array for the Li Hypo key    
    NSMutableArray *liHypoArray = [[NSMutableArray alloc] init];
    Chemical *liHypoChemical = [[Chemical alloc] initWithChemical:@"Li Hypo" 
                                            andConcentration:@"90%" 
                                                 andConstant:0.0003800
                                                 andIsLiquid:NO];
    [liHypoArray addObject:liHypoChemical];
    NSLog(@"liHypoChemical: chemName = %@, chemConcentration = %@, chemConstant = %1.6f, chemIsLiquid = %d", liHypoChemical.chemName, liHypoChemical.chemConcentration, liHypoChemical.chemConstant, liHypoChemical.chemIsLiquid);
    [liHypoChemical release];
// The array of keys for the chlorine chemicals
    NSArray *chlorineKeys = [[NSArray alloc] initWithObjects:@"Bleach", @"Trichlor", @"Dichlor", @"Cal Hypo", @"Li Hypo", nil];
// The array of values for the chlorine chemicals
    NSArray *chlorineValues = [[NSArray alloc] initWithObjects:bleachArray, trichlorArray, dichlorArray, calHypoArray, liHypoArray, nil];
    [bleachArray release];
    [trichlorArray release];
    [dichlorArray release];
    [calHypoArray release];
    [liHypoArray release];
// The dictionary to hold the arrays of chlorine chemical objects
    NSDictionary *chlorineDictionary = [[NSDictionary alloc] initWithObjects:chlorineValues forKeys:chlorineKeys];
    [chlorineValues release];
    [chlorineKeys release];
    return chlorineDictionary;
}

编辑:将名称从generateCYADictionary更改为newCYADictionary
      删除了返回后发生的版本

- (id)newCYADictionary {
    // Sets up the array for the CYA Granules key   
    NSMutableArray *cyaGranulesArray = [[NSMutableArray alloc] init];
    Chemical *cyaGranulesChemical = [[Chemical alloc] initWithChemical:@"CYA Granules" 
                                                   andConcentration:@"" 
                                                        andConstant:0.0001330
                                                        andIsLiquid:NO];
    [cyaGranulesArray addObject:cyaGranulesChemical];
    NSLog(@"cyaGranulesChemical: chemName = %@, chemConcentration = %@, chemConstant = %1.6f, chemIsLiquid = %d", cyaGranulesChemical.chemName, cyaGranulesChemical.chemConcentration, cyaGranulesChemical.chemConstant, cyaGranulesChemical.chemIsLiquid);
    [cyaGranulesChemical release];
    // Sets up the array for the Liquid Stabilizer key  
    NSMutableArray *liquidStabilizerArray = [[NSMutableArray alloc] init];
    Chemical *liquidStabilizerChemical = [[Chemical alloc] initWithChemical:@"Liquid Stabilizer" 
                                                 andConcentration:@"" 
                                                      andConstant:0.0003460
                                                      andIsLiquid:YES];
    [liquidStabilizerArray addObject:liquidStabilizerChemical];
    NSLog(@"liquidStabilizerChemical: chemName = %@, chemConcentration = %@, chemConstant = %1.6f, chemIsLiquid = %d", liquidStabilizerChemical.chemName, liquidStabilizerChemical.chemConcentration, liquidStabilizerChemical.chemConstant, liquidStabilizerChemical.chemIsLiquid);
    [liquidStabilizerChemical release];
    // The array of keys for the CYA chemicals
    NSArray *cyaKeys = [[NSArray alloc] initWithObjects:@"CYA Granules", @"Liquid Stabilizer", nil];
    // The array of values for the CYA chemicals
    NSArray *cyaValues = [[NSArray alloc] initWithObjects:cyaGranulesArray, liquidStabilizerArray, nil];
    [cyaGranulesArray release];
    [liquidStabilizerArray release];
    // The dictionary to hold the arrays of CYA chemical objects
    NSDictionary *cyaDictionary = [[NSDictionary alloc] initWithObjects:cyaValues forKeys:cyaKeys]; 
    [cyaKeys release];
    [cyaValues release];
    return cyaDictionary;
}

1 个答案:

答案 0 :(得分:3)

替换

return cyaDictionary;
[cyaDictionary release];

使用

return [cyaDictionary autorelease];

或者,您可以替换

NSDictionary *chlorineDictionary = [[NSDictionary alloc] initWithObjects:chlorineValues forKeys:chlorineKeys];

使用

NSDictionary *chlorineDictionary = [NSDictionary dictionaryWithObjects:chlorineValues forKeys:chlorineKeys];

而不是添加autorelease

在原始实现中,永远不会执行[cyaDictionary release];(因为它位于return之后)。

您可以在此方法之外使用此词典,但不应在此处释放它。

您可能还需要返回一个保留的对象(没有autorelease)并将其释放到方法之外。在这种情况下,您应该使用“new”或“alloc”启动方法名称...

编辑(重要)
你应该只使用我的一个建议。

  • 使用autorelease
  • 中的return
  • 使用dictionaryWith...
  • 在方法名称中添加“new”或“alloc”前缀,并在此方法之外释放返回的对象。

如果将alloc init替换为dictionaryWith...,则会获得一个自动释放的对象。然后,如果你在外部方法中释放它然后你有一个严重的问题(该对象将尝试在线程的当前runloop之后释放它并且它可能使应用程序崩溃,因为该对象已经被你释放)。 / p>

编辑(由于其中一条评论)
如果要创建将返回字典的属性:

// MyClass.h file
@interface MyClass : NSObject {

    ..

    NSDictionary *_dict1;

    ..

}

@property (nonatomic, retain) NSDictionary *dict1;

..

@end

// MyClass.m file

@implementation MyClass

@synthesize dict1 = _dict1;

..

- (NSDictionary *)dict1 {
    if (_dict1 == nil) {
        NSDictionary *dict1Temp = [NSDictionary new];

        // Your implementation goes here...

        self.dict1 = dict1Temp;
        [dict1Temp release];
    }
}

..

- (void)dealloc {
    [_dict1 release];
    [suoer dealloc];
}

@end