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