Ho un UIViewController presentato in modo modale. Quando guardo lo strumento di allocazioni di memoria, l'utilizzo della memoria aumenta quando viene presentata la vista, ma quando viene interrotta la memoria non viene rilasciata. Se continuo ad aprire e chiudere la vista, la memoria continua ad aumentare. Gli strumenti non riportano una perdita di memoria! Cosa potrebbe causare questo? Il codice del controller di visualizzazione è sotto (ho saltato il codice didSelectRow). Dealloc viene sempre chiamato.Possibile perdita di memoria in UIViewController con UITableView
EDIT - sto usando 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 ------------- Qualcosa non sembra avere ragione. Ho aggiunto un NSLog all'assegnazione delle celle e non viene mai chiamato, anche se le celle sono state create!
PowerUpCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
NSLog(@"new cell");
cell = [[PowerUpCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
EDIT 1 luglio ------ Ho aggiunto un controller di navigazione e ora utilizzare spinta invece di modale e questo problema è ancora qui. Ho scattato degli heap con gli strumenti spostandomi indietro e avanti tra le visualizzazioni un paio di volte e sembra che le celle siano ancora in agguato, poiché questo screenshot mostra ancora il riconoscimento dei gesti da un precedente caricamento della vista.
All'interno viewWillAppear you performOnMainThread. Non è necessario, viewWillAppear si verifica sul thread principale. –
Ho usato questo metodo solo per impostare waitUntilDone: YES, quindi ora gli array sono stati riempiti prima di disegnare la tabella. – Darren
Prova solo questo: [self workOutFullUseToDisplay]. Ti rendi conto che Objective-C è sequenziale, giusto? –