简体   繁体   中英

Obj-C UIActionSheet Memory Leaks iPhone

I'm coding a popup screen that will show up if a the value for mulValue in the settings is nil . Here is the code:

#import "FirstViewController.h"

@implementation FirstViewController

@synthesize myHelpfile = ivHelpfile; //UIAlertView
@synthesize myAboutfile = ivAboutfile; //UIAlertView
@synthesize myNoarea = ivNoarea; //UIAlertView
@synthesize myMap = ivMap; //UIImageView
@synthesize myAreapick = ivAreapick; //UIActionSheet
@synthesize myAdvancedmode = ivAdvancedmode; //NSString
@synthesize myAreaset = ivAreaset; //NSString
@synthesize myAreaarray = ivAreaarray; //NSArray

@synthesize appSettingsViewController, settingsViewController;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Wildlife";

    NSString *area  = [[NSUserDefaults standardUserDefaults] stringForKey:@"mulValue"];
    [self setMyAreaset:area];

    if ([self myAreaset] == nil) { //check if any region is selected. If not, push UIActionsheet

    NSArray *array = [[NSArray alloc] initWithObjects:      // creating array for different regions
                       [NSString stringWithString:@"Region 1"],
                       [NSString stringWithString:@"Region 2"],
                       [NSString stringWithString:@"Region 3"],
                       [NSString stringWithString:@"Region 4"],
                       [NSString stringWithString:@"Region 5"],
                       [NSString stringWithString:@"Region 6"],nil];
    [self setMyAreaarray:array];
    [array release], array = nil;       
    NSLog(@"Built areaselectArray");
    NSLog(@"Values of areaselectArray are %@",[self myAreaarray]);

    UIActionSheet *areaselect = [[UIActionSheet alloc] initWithTitle:@"Select your current area" //creation of popup Area Selection
                                                            delegate:self 
                                                   cancelButtonTitle:nil 
                                              destructiveButtonTitle:nil 
                                                   otherButtonTitles:nil];
        [self setMyAreapick:areaselect];
        [areaselect release], areaselect = nil;

    int countarray = [[self myAreaarray] count];

    for (int i = 0; i < countarray; i++) { //building list from array

        [[self myAreapick] addButtonWithTitle:[[self myAreaarray] objectAtIndex:i]];

    }
    [[self myAreapick] addButtonWithTitle:@"Cancel"];
    [self myAreapick].cancelButtonIndex = countarray;
    [[self myAreapick] showInView:self.view];//show the general UIActionSheet instance
    NSLog(@"Out of viewDidLoad");
    }
    else {
        NSLog(@"Area is %@, no need for areaselectArray",area);
        }   

}


-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger )buttonIndex
{
    int countarray = [[self myAreaarray] count];

    if (buttonIndex != countarray) { //cancel button is at countarray, so for anything that is not cancel, do:
            NSString *area = [[self myAreaarray] objectAtIndex:(buttonIndex)];
            [self setMyAreaset:area];
            [[NSUserDefaults standardUserDefaults] setObject:[self myAreaset] forKey:@"mulValue"];
            [[NSUserDefaults standardUserDefaults] synchronize]; //sync
            NSLog(@"Released areaselectArray");
        }
    else {
    }

}

And in my FirstViewController.h I have:

@interface FirstViewController : UIViewController <UIActionSheetDelegate, IASKSettingsDelegate, UIAlertViewDelegate> {
    UIAlertView *ivHelpfile;
    UIAlertView *ivAboutfile;
    UIAlertView *ivNoarea;
    UIActionSheet *ivAreapick;
    UIImageView *ivMap;
    NSString *ivAdvancedmode;
    NSString *ivAreaset;
    NSArray *ivAreaarray;

}

@property(nonatomic, retain) UIAlertView *myHelpfile;
@property(nonatomic, retain) UIAlertView *myAboutfile;
@property(nonatomic, retain) UIAlertView *myNoarea;
@property(nonatomic, retain) UIActionSheet *myAreapick;
@property(nonatomic, retain) UIImageView *myMap;
@property(nonatomic, copy) NSString *myAdvancedmode;
@property(nonatomic, copy) NSString *myAreaset;
@property(nonatomic, retain) NSArray *myAreaarray;

When I run my app in the simulator with Instruments running, I get a memory leak whenever I scroll the list of rows (as built by [self myAreaarray] ) and release my finger. The weird thing is, it has not really done anything else at that point. The main view is loaded, but it would be strange that that would cause a memory leak based on scrolling through the list.

The leaks I get in Instruments are the following:

_NSCFType 48 bytes CoreGraphics CGTypeCreateInstanceWithAllocator

UIDeviceWhiteColor 16 bytes UIKit +[UIColor allocWithZone:]

When I scroll through the list again, more of those errors show up. It looks like I'm allocating something and not releasing it (while I'm scrolling the list?), but I can't find it at this point.

Any help would be appreciated!

I'm seeing it as well, even abstracting all your app code from it:

 UIActionSheet *as = [[UIActionSheet alloc] initWithTitle:@"Test" delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];

 for (int i = 0; i < 100; i++) {
     [as addButtonWithTitle:[NSString stringWithFormat:@"Button %i", i]];
 }
 as.cancelButtonIndex = 99;
 as.destructiveButtonIndex = 0;

 [as showInView:self.view];
 [as release];

When running through Instruments memory leak profiler, each display of the action sheet yieds 6 UIDeviceWhiteColor leaks and 4 CGColor leaks. Looks to me like this is a bug in UIKit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM