2011-12-15 38 views
4

对于我最近的一个学校项目,我正在创建一个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项目。希望有人能帮忙:请让我知道是否需要发布更多代码来澄清事情。

在此先感谢!

回答

0

从来没有找到解决方案本身,所以我使用了一种解决方法:通过用NSTableView组件替换NSPickerView,泄漏不再发生。对于每个注意到该问题并试图找到解决方案的人:感谢您的尝试!

0

尝试删除-(void)dealloc方法。当你使用ARC时不应该实现它。如果您不使用ARC,则需要拨打[super dealloc]

+0

该项目已经完成:我用一个NSTableView组件代替,它修复了泄漏。我无法再访问这些文件,因此无法再尝试您的解决方案。不过,谢谢你的建议! – Tybs 2012-04-16 13:47:36

0

我有类似的问题。它只发生在UIPickerView超出界限时。我修复它的方式是永远不会让UIPickerView移出界限(只需淡入和淡出以取消隐藏UIPickerView)。可能是UIKit中的一个错误。