Possible memory leak in UIViewController with UITableView

I have a UIViewController that is presented modally. When I look at the memory allocation tool, the memory usage increases when the view is displayed, but when it leaves the memory, it is not released. If I keep opening and closing the view, the memory just gets higher. Tools do not report a memory leak! What could be the reason for this? Controller view code below (I skipped didSelectRow code). Dealloc is always called.

EDIT - I use ARC

.h

#import <UIKit/UIKit.h>
@class OutlineTextUILabel;

@interface StoreViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {

    int starCount;
    NSMutableArray *_singleUseArray;
    NSMutableArray *_fullUseArray;

}

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet OutlineTextUILabel *starCountLbl;
- (IBAction)exitBtnPressed:(id)sender;

.m

#import "StoreViewController.h"
#import "NSUserDefaults+MPSecureUserDefaults.h"
#import "PowerUpCell.h"
#import "OutlineTextUILabel.h"
#import "PowerUpSingleton.h"
#import "PowerUp.h"

#define kPrefsNumberOfStars             @"numberOfStars"

@interface StoreViewController ()

@end

@implementation StoreViewController
@synthesize tableView = _tableView;
@synthesize starCountLbl;

#pragma mark View Methods

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Display star count
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    BOOL valid = NO;
    starCount = [prefs secureIntegerForKey:kPrefsNumberOfStars valid:&valid];
    if (!valid) {
        NSLog(@"Stars Tampered With!");
        self.starCountLbl.text = @"Err";
    } else {
        self.starCountLbl.text = [NSString stringWithFormat:@"%d",starCount];
    }

    // Tableview setup
    CGRect frame2 = CGRectMake(0, 0, 320, 40);
    UIView *footer = [[UIView alloc] initWithFrame:frame2];
    footer.backgroundColor = [UIColor clearColor];
    self.tableView.tableFooterView = footer;
    self.tableView.opaque = NO;
    self.tableView.backgroundView = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];

    if (![[PowerUpSingleton sharedList] refreshArray]) {
        NSLog(@"Error, %s",__FUNCTION__);
    } else {
        [self performSelectorOnMainThread:@selector(workOutSingleUseToDisplay) withObject:nil waitUntilDone:YES];
        [self performSelectorOnMainThread:@selector(workOutFullUseToDisplay) withObject:nil waitUntilDone:YES];
        [self.tableView reloadData];
    }
}

- (void)workOutSingleUseToDisplay
{
    _singleUseArray = [[NSMutableArray alloc] init];
    for (PowerUp *pu in [[PowerUpSingleton sharedList] sharedArray]) {
        if (!pu.fullUnlock) {
            [_singleUseArray addObject:pu];
        }
    }
}

- (void)workOutFullUseToDisplay
{
    _fullUseArray = [[NSMutableArray alloc] init];
    for (PowerUp *pu in [[PowerUpSingleton sharedList] sharedArray]) {
        if (pu.prefFullName != nil) {
            [_fullUseArray addObject:pu];
        }
    }

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}

- (void)viewDidUnload {
    [self setTableView:nil];
    [self setStarCountLbl:nil];
    [super viewDidUnload];
}

#pragma mark TableView Setup Methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 2;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return @"Single Use";
    } else if (section == 1) {
        return @"Use forever";
    }

    return nil;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        return [_singleUseArray count];
    } else if (section == 1) {
        return [_fullUseArray count];
    }

    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier;
    if (indexPath.section == 0) {
        cellIdentifier = @"powerUpCellSingleUse";
    } else if (indexPath.section == 1) {
        cellIdentifier = @"powerUpCell";
    }

    PowerUpCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[PowerUpCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

    if (indexPath.section == 0) {
        PowerUp *tmpPU = [_singleUseArray objectAtIndex:indexPath.row];
        cell.descriptionLbl.text = tmpPU.displayName;
        int cost = tmpPU.costSingle;
        cell.costLbl.text = [NSString stringWithFormat:@"%d",cost];
        if (cost > starCount) {
            cell.costLbl.textColor = [UIColor redColor];
        } else {
            cell.costLbl.textColor = [UIColor blueColor];
        }
        int howMany = tmpPU.numberOwned;
        cell.howManyLbl.text = [NSString stringWithFormat:@"%d",howMany];

    } else if (indexPath.section == 1) {
        PowerUp *tmpPU = [_fullUseArray objectAtIndex:indexPath.row];
        cell.descriptionLbl.text = tmpPU.displayName;
        int cost = tmpPU.costFull;
        cell.costLbl.text = [NSString stringWithFormat:@"%d",cost];
        if (cost > starCount) {
            cell.costLbl.textColor = [UIColor redColor];
        } else {
            cell.costLbl.textColor = [UIColor blueColor];
        }
        if (tmpPU.fullUnlock) {
            cell.costLbl.textColor = [UIColor greenColor];
            cell.costLbl.text = @"---";
        }
    }

    return cell;
}

#pragma mark -

- (IBAction)exitBtnPressed:(id)sender
{
    [self dismissModalViewControllerAnimated:YES];
}

- (void)dealloc
{
    NSLog(@"%s",__FUNCTION__);
    self.tableView = nil;
    self.starCountLbl = nil;
}

@end

EDIT ------------- Something seems to be wrong. I added an NSLog to the alloc cell, and it was never called, even if the cells were created!

PowerUpCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        NSLog(@"new cell");
        cell = [[PowerUpCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

1 ------ push , . , , , , - . screen shot

+5
5

, IBOutlets weak strong.

, XCode, .

, XCode IBOutlets, Interface Builder, .

+3

, , :

1) , Zombies , , , (Edit scheme β†’ Run β†’ Diagnostics).

2) ARC, , , UITableView /NIB? , , NSLog() , , dequeueReusableCellWithIdentifier , cellIdentifier. .

PowerUpCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        NSLog(@"new cell");
        cell = [[PowerUpCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

UITableView UITableViewCells . , , UITableView (, , , ).

+2

[EDIT]

viewWillAppear , , else. , workOutSingleUseToDisplay workOutFullUseToDisplay. , , _singleUseArray _fullUseArray. , , , dealloc, . , , , , .

[] , viewDidLoad alloc. dealloc [footer release]. ! _singleUseArray _fullUseArray

0

, anwer, - :

:

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet OutlineTextUILabel *starCountLbl;

( "" ), weak propoerty assign.

dealloc

self.tableView = nil;
self.starCountLbl = nil;

, !

:

@property (nonatomic, retain) IBOutlet UITableView *tableView;
@property (nonatomic, retain) IBOutlet OutlineTextUILabel *starCountLbl;

(void)setTableView(UITableView *)newTableView {
    [tableView release];
    if(newTableView != nil)
        tableView = [newTableView retain];
}

.

0

, Leaks . "" . Analyze, , .

:

 PowerUpCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 if (cell == nil) {
    NSLog(@"new cell");
    cell = [[PowerUpCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
 }

, cell nil... API doc dequeueReusableCellWithIdentifier::



UITableViewCell nil, .

, , , :

_singleUseArray = [[NSMutableArray alloc] init];

_fullUseArray = [[NSMutableArray alloc] init];

NSMutableArray *_singleUseArray;
NSMutableArray *_fullUseArray;

, __strong. , . ?

NSMutableArray * __weak _singleUseArray;
NSMutableArray * __weak _fullUseArray;

,

_singleUseArray = [[NSMutableArray alloc] init];

_fullUseArray = [[NSMutableArray alloc] init];

nil ?

_singleUseArray = nil;
_singleUseArray = [[NSMutableArray alloc] init];

_fulUseArray = nil;
_fullUseArray = [[NSMutableArray alloc] init];
0

All Articles