CoreData утечки, когда представление разрушено - PullRequest
0 голосов
/ 23 января 2011

Я пытаюсь завершить приложение, но у меня возникают некоторые утечки памяти с CoreData, когда я удаляю представление из стека навигации, даже если я выпустил все, что создал.

По сути, вызывается следующий методсогласно представлению под ним.

+ (NSMutableArray *)getStoriesForSubscription:(Subscriptions *)s {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *storiesEntity = [NSEntityDescription entityForName:@"Articles" inManagedObjectContext:ikub.context];
[request setEntity:storiesEntity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(belongsTo == %@)", s];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"pubDate" ascending:NO selector:nil];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors]; 
NSError *error = nil;

NSMutableArray *stories = (NSMutableArray*)[ikub.context executeFetchRequest:request error:&error];
if (![ikub.context save:&error]) { NSLog(@"Cannot fetch the folders from the fetch request."); }
[sortDescriptors release];
[sortDescriptor release];
[request release];
return stories;
}


@implementation SubscriptionStories

@synthesize storiesTable, stories, subscription;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [stories count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
  if (cell == nil) {
  cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
 }
 int index = [indexPath row];
 cell.textLabel.text   = [[stories objectAtIndex:index] title];
 cell.detailTextLabel.text = [[stories objectAtIndex:index] desc];
 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;


 if ([[[stories objectAtIndex:index] read] isEqualToNumber:[NSNumber numberWithBool:NO]]) {
 cell.textLabel.textColor = [UIColor blackColor];
 } else {
 cell.textLabel.textColor = [UIColor grayColor];
 }

 return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 StoryDetails *details = [[StoryDetails alloc] init];
 details.title = @"Detaje";
 details.t = [[stories objectAtIndex:[indexPath row]] title];
 details.d = [[stories objectAtIndex:[indexPath row]] desc];
 details.l = [[stories objectAtIndex:[indexPath row]] link];
 details.g = [[stories objectAtIndex:[indexPath row]] guid];
 details.p = (NSString *)[[stories objectAtIndex:[indexPath row]] pubDate];
 [SubscriptionsController setStoryAsRead:[[stories objectAtIndex:[indexPath row]] link] forSubscription:subscription];
 [self.navigationController pushViewController:details animated:YES];
 [details release];
}

- (void)viewDidLoad { 
[super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {
stories = [[SubscriptionsController getStoriesForSubscription:subscription] retain];
[storiesTable reloadData];
}

- (void)viewWillDisappear:(BOOL)animated { 
[stories release];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
[super viewDidUnload];
}

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

Приборы говорят, что утечка происходит в этой строке:

stories = [[SubscriptionsController getStoriesForSubscription:subscription] retain];

Ответы [ 3 ]

0 голосов
/ 23 января 2011

мои предложения:

удалить (еще одну?) Утечку, изменив свое создание UITableViewCell, чтобы оно возвращало автоматически освобожденную ячейку

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"] autorelease];
    ...
}

, если это не помогло.(У меня были утечки, инструменты были в нескольких милях от настоящей утечки).измените ваш метод viewWillDisappear на что-то вроде этого

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [stories release];
    stories = nil;
}

и добавьте еще один выпуск для историй в dealloc

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

Возможно, существуют неясные способы, которыми происходит освобождение без вызова метода viewWillDisappear:
Я обычно выпускаю все в dealloc.Пока вы убедитесь, что вы установили объект равным nil, когда вы освободили его другим способом, ничего плохого не произойдет.

0 голосов
/ 27 января 2011

Утечка была в совершенно другом месте. Инструменты не всегда правы.

0 голосов
/ 23 января 2011

Если вы объявили свойство историй с удержанием, то дополнительное удержание не требуется.

self.stories = [SubscriptionsController getStoriesForSubscription:subscription];
...