【问题标题】:CoreData leaks when view is destroyed视图被销毁时CoreData泄漏
【发布时间】:2011-06-14 00:34:20
【问题描述】:

我正在尝试完成一个应用程序,但当我从导航堆栈中删除视图时,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];

【问题讨论】:

    标签: iphone ios core-data memory-leaks instruments


    【解决方案1】:

    如果你已经用retain声明了属性stories,那么额外的retain就没有必要了。

    self.stories = [SubscriptionsController getStoriesForSubscription:subscription];
    

    【讨论】:

    • 如果我删除了保留,当我回到这个视图时应用程序会崩溃。
    • 我只是在故事之前添加了自我,将保留留在那里,我得到了另一种泄漏。这次在 Foundation 中,-[NSArray(NSKeyValueSorting)] 在同一行。 :((((
    • 如果您将self.stories = [[..] retain]; 与您保留两次的retain 属性一起使用,那么stories = [[.. ] retain]; 没有任何问题,这当然会泄漏。
    • 当我不使用 self.stories 时,会有泄漏。当我使用它时,应用程序会崩溃。
    【解决方案2】:

    我的建议:

    通过更改 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 的方式很模糊。
    我通常在 dealloc 中释放所有内容。只要确保在以另一种方法释放对象时将对象设置为 nil,就不会发生任何不好的事情。

    【讨论】:

      【解决方案3】:

      泄漏发生在完全不同的地方。仪器并不总是正确的。

      【讨论】:

        猜你喜欢
        • 2022-12-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-18
        • 1970-01-01
        • 2016-12-06
        • 1970-01-01
        • 2011-04-17
        • 1970-01-01
        相关资源
        最近更新 更多