0

我正在尝试在我的代码(2.5mb)中调试内存泄漏,它似乎指向 _ prepareResultsFromResultSetwithin NSFetchedResultsController。我有 2 个视图控制器(A 和 B),视图控制器 B 从视图控制器 A 推送到导航控制器。

在 BI 中执行如下 NSFetchRequest使用: .hNSFetchedResultsController

@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 后保留以下数据:

在此处输入图像描述

如果我再次回到控制器 B,则会添加另一组此内存并且永远不会删除。但是,如果我第三次这样做,金额不会增加。我假设正在进行某种缓存,谁能告诉我如何删除这些数据或如何正确释放NSFetchedResultsController.

如果您需要更多信息,请随时询问。

4

2 回答 2

2

通常你不应该担心 Core Data 中的内存管理。是的,在底层涉及缓存机制。

无论如何,有两种不同的方法可以“消除”内存。

首先是refreshObject:mergeChanges:方法。传递给它NO,它允许修剪对象图。换句话说,它会丢弃任何尚未保存到存储中的更改数据。

覆盖willTurnIntoFaultdidTurnIntoFault查看它的实际效果。

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

希望有帮助。

于 2013-01-28T22:40:00.613 回答
0

你永远不应该自己调用 dealloc,即使是在你自己的对象上。这是系统自己做的事情。

于 2013-01-29T13:13:46.490 回答