对于我最近的一个学校项目,我正在创建一个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