Утечки памяти в UITableView с NSMutableArray - Как их остановить? - PullRequest
0 голосов
/ 19 января 2011

Я довольно новичок в разработке Objective-C, и я начинаю тестировать свое приложение на предмет утечек и исправления всего, что я мог изначально сделать неправильно.Я последовал примерам из книги, которую купил, и развил эти идеи.Инструмент Leaks сообщает мне в методе tableView cellForRowAtIndexPath, что у меня есть утечка, и я не уверен, как ее исправить.

Вот связанное содержимое .h:

@interface NewsListViewController : UITableViewController<UIActionSheetDelegate> {
NSMutableArray *newsList, *account, *playerList;}

А вот связанное содержимое .m:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)ip {
static NSString *CellIdentifier = @"NewsCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                  reuseIdentifier:CellIdentifier];
    [cell autorelease];
}

NSManagedObject *uNews = [newsList objectAtIndex:[ip row]];

NSManagedObjectContext *playerDBContext = [[AppController sharedAppController] managedObjectContext];

NSFetchRequest *playerDBRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *playerDBEntity = [NSEntityDescription entityForName:@"Players"
                                                  inManagedObjectContext:playerDBContext];
[playerDBRequest setEntity:playerDBEntity];

NSPredicate *playerDBPredicate = [NSPredicate predicateWithFormat:@"playerID=%@", [uNews valueForKey:@"playerID"]];
[playerDBRequest setPredicate:playerDBPredicate];

NSError *playerDBError;

NSArray *playerDBList = [playerDBContext executeFetchRequest:playerDBRequest error:&playerDBError];

[playerDBRequest release];

playerList = [playerDBList mutableCopy];

NSString *playerInformation;

if (![playerDBList count] == 0) {
        NSManagedObject *playerInfo = [playerList objectAtIndex:0];
        playerInformation = [NSString stringWithFormat:@"%@, %@ (%@-%@)", [playerInfo valueForKey:@"playerLastName"],
                                                                          [playerInfo valueForKey:@"playerFirstName"],
                                                                          [playerInfo valueForKey:@"team"],
                                                                          [playerInfo valueForKey:@"position"]];
} else {
    //NSInteger playerID = (NSInteger *)[uNews valueForKey:@"playerID"];
    [self addPlayer:(NSInteger *)[uNews valueForKey:@"playerID"]];
    NSLog(@"%@", [uNews valueForKey:@"playerID"]);
    playerInformation = [uNews valueForKey:@"playerInfo"];
}

cell.textLabel.text = playerInformation;
cell.detailTextLabel.text = [uNews valueForKey:@"news"];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

return cell;}

Выдает ошибку на playerList = [playerDBList mutableCopy];линия - Помощь с тем, как исправить и объяснение будет принята с благодарностью.Вероятно, это происходит из-за перераспределения без выпуска, но когда я попытался использовать [playerList release];в конце cellForRowAtIndexPath мое приложение вылетает.

Ответы [ 2 ]

2 голосов
/ 19 января 2011

Свойства сделали бы это "просто работой".

.h:

...
@property (nonatomic, retain) NSMutableArray *playerList;
...       

.m:

@implementation MyClass 

@synthesize playerList;

... then in your cellForIndexPath method ...

    self.playerList = [[playerDBList mutableCopy] autorelease];

...

- (void)dealloc {
    [playerList release];
    [super dealloc];
}

Свойство, объявленное как «retain», автоматически обрабатывает управление памятью при назначении свойства, освобождая старое значение, если оно существует, до сохранения нового.

1 голос
/ 19 января 2011

Выпуск, который вы пробовали, потерпел крах, потому что первый раз в списке игроков еще не был назначен, а вы выпустили ноль Но во второй раз через это что-то происходит, и вы это пропускаете. Всякий раз, когда я снова использую удерживающий указатель, я делаю

if( playerList )
   [playerList release];
playerList = [playerDBList mutableCopy];

просто чтобы быть в безопасности.

...