在NSFetchedResultsController上调用dealloc时内存不释放

时间:2013-01-28 22:22:27

标签: objective-c core-data memory-leaks dealloc

我正在尝试调试代码中的内存泄漏(2.5mb),它似乎指向prepareResultsFromResultSet中的_ NSFetchedResultsController。我有2个viewControllers(A& B),viewController B从viewController A推送到navigationController。

在B中,我使用NSFetchRequest执行NSFetchedResultsController,如下所示:

·H

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSString *sMapSlug;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andMapSlug: (NSString *)slug;

的.m

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andMapSlug: (NSString *)slug
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.sMapSlug = [NSString stringWithString:slug];
    }
    return self;
}
- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil)
        return _fetchedResultsController;

    Singleton *singleton = [Singleton sharedSingleton];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DescriptionEntity" inManagedObjectContext:[singleton managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"map.sName" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"map.sSlug LIKE %@", self.sMapSlug];
    [fetchRequest setFetchBatchSize:8];
    [fetchRequest setPredicate:myPredicate];

    // Finally check the results
    NSError *error;
    NSArray *fetchedObjects = [[singleton managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    for (DescriptionEntity *desc in fetchedObjects)
    {
        NSLog(@"Maps present in database: %@", desc.map.sName);
    }        

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[singleton managedObjectContext] sectionNameKeyPath:nil cacheName:@"Test1"];
    self.fetchedResultsController = theFetchedResultsController;
    self.fetchedResultsController.delegate = self;
    //[self.fetchedResultsController performFetch:NULL];
    [theFetchedResultsController release];
    [fetchRequest release];
    [sort release];

    return _fetchedResultsController;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self.fetchedResultsController fetchRequest];
}

使用fetchRequest可以很好地加载所有东西,如果需要我可以访问我的数据,但是我现在已经把它拿出来所以我知道NSFetchedRequestController中没有任何数据被使用。当我返回导航堆栈时,调用控制器B的dealloc,然后执行以下操作:

- (void)dealloc {
    self.fetchedResultsController.delegate = nil;
    [_fetchedResultsController release];
    [sMapSlug release];

    [super dealloc];
}

当我在Instruments中对此进行堆镜像时,我会在调用dealloc后看到以下数据:

enter image description here

如果我再次返回控制器B,则会添加另一组此内存并且永远不会删除。但是,如果我第三次执行此操作,则金额不会增加。我假设存在某种缓存,有人可以告诉我如何删除此数据或如何正确释放NSFetchedResultsController

如果您需要更多信息,请随时提出。

2 个答案:

答案 0 :(得分:2)

通常您不必担心Core Data中的内存管理。是的,在引擎盖下有一个缓存机制。

无论如何,有两种不同的方法来“解雇”记忆。

第一种是refreshObject:mergeChanges:方法。传递给它NO,它允许修剪对象图。换句话说,它会丢弃任何尚未保存到商店的已更改数据。

覆盖willTurnIntoFaultdidTurnIntoFault以查看其实际效果。

另一种是在托管上下文上调用reset。显然,这会删除上下文包含的所有对象。

希望有所帮助。

答案 1 :(得分:0)

你永远不应该自己调用dealloc,甚至不要自己调用dealloc。这是系统自己做的事情。