對於我最近的一個學校項目,我正在創建一個iPad/iPhone應用程序。一段時間以來,我一直在解決某個內存泄漏的問題。我的應用程序從一個特定的視圖控制器(VCMainStatistics_iPad)開始。從那裏,我推着另一個視圖控制器(VCSocialMedia_iPad)。之後,我回到第一個視圖控制器。Xcode 4.2.1:UIPickerView導致內存泄漏,使用ARC
當我重複這個序列時,我注意到(通過使用Instruments - Activity Monitor),應用程序的內存使用量不斷增加。通過禁用部分代碼,我最終發現它與pickerView有關。此代碼不會泄漏:但是,當我增加行數時,泄漏開始出現(大約每行0.07 MB)。顯然,這就是爲什麼我認爲pickerView是泄漏的原因。我一直試圖刪除pickerView中的子視圖,然後再取消分配,將pickerView設置爲零,還有很多其他的東西......沒有任何東西可以解決這個問題。爲了讓事情更清楚些,我會發布更多的代碼。
頭文件:
#import "UniversalViewController.h"
#define DATATYPE_SOCIALMEDIA 0
@interface VCSocialMedia_iPad : UniversalViewController <UIPickerViewDataSource, UIPickerViewDelegate>
{
NSArray *lMediaTypes;
NSMutableArray *lMediaData;
__weak IBOutlet UIPickerView *pkSocialMedia;
__weak IBOutlet UILabel *lblGraph;
}
@end
PickerView委託方法:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
// Get key of requested row
NSString *title = [[lMediaTypes objectAtIndex:row] capitalizedString];
// Capitalize first letter
title = [title capitalizedString];
// Return
return title;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// Make or clear data lists
if(lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] == nil){
lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] = [[NSMutableArray alloc] init];
}
else{
[lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] removeAllObjects];
}
if(lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] == nil){
lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] = [[NSMutableArray alloc] init];
}
else{
[lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] removeAllObjects];
}
// Get required key
NSString *dictKey = [lMediaTypes objectAtIndex:row];
if([dictKey isEqualToString:@"total_views"]){
return;
}
// Adjust graph label
lblGraph.text = [NSString stringWithFormat:@"Stats from %@", dictKey];
// Get data of selected row
NSArray *mediaData = [lMediaData objectAtIndex:row];
// Add each day to data lists: inversed order
for(int day = [mediaData count]-1; day >= 0; day--){
NSDictionary *dayData = [mediaData objectAtIndex:day];
dictKey = @"wpsd_trends_date";
NSString *date = [dayData objectForKey:dictKey];
// Remove 00:00:00
date = [date stringByReplacingOccurrencesOfString:@" 00:00:00" withString:@""];
[lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] addObject:date];
dictKey = @"wpsd_trends_stats";
NSString *stats = [dayData objectForKey:dictKey];
[lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] addObject:stats];
}
// Update the graphs
[self updateGlobalScreen];
}
PickerView數據源的方法:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [lMediaTypes count];
}
取消分配:
- (void)dealloc
{
pkSocialMedia = nil;
lblGraph = nil;
lMediaData = nil;
lMediaTypes = nil;
}
我最近纔將項目轉換爲Objective-C ARC,所以這個問題很有可能與我對這個概念缺乏經驗有關。除此之外,這也是我的第一個Xcode項目。希望有人能幫忙:請讓我知道是否需要發佈更多代碼來澄清事情。
在此先感謝!
該項目已經完成:我用一個NSTableView組件代替,它修復了泄漏。我無法再訪問這些文件,因此無法再嘗試您的解決方案。不過,謝謝你的建議! – Tybs 2012-04-16 13:47:36