对于我最近的一个学校项目,我正在创建一个iPad / iPhone应用程序。几天来,我一直在研究一个内存泄漏的问题。我的应用程序从特定的视图控制器(VCMainStatistics_iPad)开始。从那里,我推送另一个视图控制器(VCSocialMedia_iPad)。之后,我回到第一个视图控制器。
当我重复这个序列时,我注意到(通过使用Instruments - Activity Monitor)应用程序的内存使用量不断增加。通过禁用部分代码,我最终发现它与pickerView有关。此代码没有泄漏:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 0;
}
然而,当我增加行数时,泄漏开始出现(每行大约0.07 MB)。显然,这就是为什么我认为pickerView是泄漏的原因。我一直试图在解除分配之前从pickerView中删除子视图,将pickerView设置为nil,还有很多其他的东西......没有什么能解决这个问题。为了让事情更清楚一点,我会发布更多代码。
标题文件:
#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项目。希望有人可以提供帮助:如果我需要发布更多代码来澄清事情,请告诉我。
提前致谢!
答案 0 :(得分:0)
尝试删除-(void)dealloc
方法。当您使用ARC时,不应该实现它。如果您不使用ARC,则需要致电[super dealloc]
。
答案 1 :(得分:0)
从未找到解决方案本身,因此我使用了一种解决方法:通过将NSPickerView替换为NSTableView组件,泄漏不再发生。对于每个注意到这个问题并试图找到解决方案的人:谢谢你的尝试!
答案 2 :(得分:0)
我遇到了类似的问题。它只发生在UIPickerView超出边界时。我修复它的方法是永远不要让UIPickerView移出界限(简单地淡入并淡出以取消隐藏/隐藏UIPickerView)。可能是UIKit中的一个错误。