0

这里有两个方法返回我的自定义四元对象的字典。他们将字符串,浮点数和BOOL数组放入Chemical对象中,然后从数组中构建字典。我对整个内存管理游戏已经足够新颖了,以至于当我拥有某些东西以及何时发布它时,我并不总是很确定。我正在制作各种各样的字符串。客观c内存泄漏

事情是这样的:静态分析认为没有问题与第一种方法,- (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; 
} 

回答

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)并将其释放到方法外部。在这种情况下,你应该用“新”或“黄金” ......

EDIT(重要)启动方法名称:
你应该只使用我的建议之一。

  • 使用autoreleasereturn线
  • 使用dictionaryWith...
  • 添加“新”或“黄金”前缀的方法名和释放这种方法外返回的对象。

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

EDIT(由于一个评论)
如果你想创建一个将返回字典的属性:

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

谢谢迈克尔,我改变了方法名' - (ID)例如newChlorineDictionary。在我称之为的方法中,我已经在将它设置为下一个视图控制器中的属性之后释放了返回的字典。这似乎满足了静态分析仪。 – Steve 2010-07-28 06:14:14

+0

我尝试了你的第二个建议 - 删除了'alloc',但是我得到了一个关于没有响应某些类方法的错误 - 太累了无法重做它,现在写下错误......但是我不认为你可以忽略'当你创建一个新对象时'alloc'。无论如何,它似乎现在就可以建立起来了 - 我会和Instruments一起运行,看看它说了什么......再次感谢! – Steve 2010-07-28 06:14:52

+0

唉,仪器中我每次在我的表格视图中生成新的控制器时会泄漏一些东西。泄漏发生在这个班,虽然我猜它可能是另一种方法。但是静态分析器没有捕获任何东西。当我以模态方式呈现选取器视图时,我也在泄漏,但这是另一个帖子... – Steve 2010-07-28 06:21:51