2011-10-04 70 views
1

構建自定義的UIPickerView,以便我的用戶可以選擇24小時時間,而無需進入「設置」應用程序並打開整個手機的24小時時間。有一些字符串和數組的一些頑固的泄漏,我真的可以使用一些幫助。UIPickerView方法中的奇怪泄漏

只有三個地方使用字符串創建數組。小時和分鐘都是NSArray綜合屬性以及ivars。

一)在viewWillAppear中:動畫,這裏的字符串和數組實際創建:

if (TwentyFourHourMode) { 
    //set up arrays for 24 hour picker 

    NSMutableArray *hoursMutable = [[NSMutableArray alloc] init]; 
    NSString *hourString; 
    for (int i = 0; i < 24; i++) { 
     if (i < 10) { 
      hourString = [NSString stringWithFormat:@"0%i", i]; 
     } else { 
      hourString = [NSString stringWithFormat:@"%i", i]; 
     } 
     [hoursMutable addObject:hourString]; 
    } 
    self.hours = [[NSArray alloc] initWithArray:hoursMutable]; 
    [hoursMutable release]; 

    NSMutableArray *minutesMutable = [[NSMutableArray alloc] init]; 
    NSString *minuteString; 
    for (int i = 0; i < 60; i++) { 
     if (i < 10) { 
      minuteString = [NSString stringWithFormat:@"0%i", i]; 
     } else { 
      minuteString= [NSString stringWithFormat:@"%i", i]; 
     } 
     [minutesMutable addObject:minuteString]; 
    } 
    self.minutes = [[NSArray alloc] initWithArray:minutesMutable]; 
    [minutesMutable release]; 
    //more stuff which does not leak or reference the arrays/strings in question 
} else { 
    //unrelated crap 
} 

二)我UIPickerView委託方法 - 使用這兩個數組的一切:

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 
    return 2; 
} 

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 
    if (component == 0) { 
     return self.hours.count; 
    } else if (component == 1) { 
     return self.minutes.count; 
    } else { 
     return 0; 
    }  
} 

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 
{ 
    if (component == 0) { 
     return [self.hours objectAtIndex:row]; 
    } else if (component == 1) { 
     return [self.minutes objectAtIndex:row]; 
    } else { 
     return nil; 
    } 
} 

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { 
    switch(component) { 
     case 0: return 44; 
     case 1: return 50; 
     default: return 44; 
    } 

} 

- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
{ 
    if (component == 0) { 
     [hour24 release]; 
     hour24 = [self.hours objectAtIndex:row]; 
     [hour24 retain]; 
    } else if (component == 1) { 
     [minute24 release]; 
     minute24 = [self.minutes objectAtIndex:row]; 
     [minute24 retain]; 
    } 

Ç )和最後但並非最不重要的,在dealloc:

//set arrays to nil 
self.hours = nil; 
self.minutes = nil; 

//release arrays 
[hours release]; 
[minutes release]; 

分析即將到來的乾淨,但在結構告訴我,hourString,minuteString和self.hours全部被泄露。真正讓我瘋狂的是self.minutes沒有被泄漏,它與self.hours似乎是相同的代碼格式 - 我甚至複製粘貼,仍然得到相同的泄漏/無泄漏組合。

如果我能弄清楚這是從哪裏來的,我會被詛咒的。有任何想法嗎?你們都可能需要幫助嗎?多謝你們!

編輯:EmptyStack的建議停止self.hoursminuteString被泄露,但hourString仍然漏水,現在有一個新的泄漏這段代碼有以下的東西上面viewWillAppear:animatedself.incomingTime是合成NSString屬性,這裏所有的數組在本地初始化):

NSArray *splitStrings = [self.incomingTime componentsSeparatedByString:@":"]; 
NSString *hourToDisplay = [splitStrings objectAtIndex:0]; 
//set this here so it doesn't give a null value 
hour24 = [[NSString alloc] initWithString:hourToDisplay]; 
NSString *minuteSplitter = [splitStrings objectAtIndex:1]; 
NSArray *splitMinutes = [minuteSplitter componentsSeparatedByString:@" "]; 
NSString *minuteToDisplay = [splitMinutes objectAtIndex:0]; 
minute24 = [[NSString alloc] initWithString:minuteToDisplay]; 

編輯2:哦,看哭出聲來,現在minuteString再次泄漏。我要在我的頭爆炸之前睡覺。任何建議一夜之間將是最受歡迎的。

回答

2

的問題是下面幾行,

self.hours = [[NSArray alloc] initWithArray:hoursMutable]; 
self.minutes = [[NSArray alloc] initWithArray:minutesMutable]; 

看來小時分鐘「保留特性」,並同時將其分配給的屬性你分配對象。例如,在第一行上,[NSArray alloc]retainCount增加1,而設置者self.hours繼而增加了保留計數1。最後retainCount變爲2,即使在您釋放這些對象後,這也會導致泄漏。在這些情況下,您可以使用便利的構造函數。

self.hours = [NSArray arrayWithArray:hoursMutable]; 
self.minutes = [NSArray arrayWithArray:minutesMutable]; 

即使一個簡單的方法是直接分配這樣的陣列,

self.hours = hoursMutable; 
self.minutes = minutesMutable; 
+0

那麼,幫助 - self.hours和minuteString不再被泄漏。但是,hourString仍然在泄漏,現在有一個新的數組泄漏:'NSArray * splitStrings = [self.incomingTime componentsSeparatedByString:@「:」];' – DesignatedNerd

1

好了,終於找到了它,穿過這人磕磕絆絆的未來:hour24minute24沒有被正確在dealloc中發佈,所以它泄漏字符串和數組遍及整個地方。我通過評論第二次編輯中發佈的代碼並逐行將其重新排列,直到泄漏出現,找到了它。感謝您的建議!