我正在尝试调试代码中的内存泄漏(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后看到以下数据:
如果我再次返回控制器B,则会添加另一组此内存并且永远不会删除。但是,如果我第三次执行此操作,则金额不会增加。我假设存在某种缓存,有人可以告诉我如何删除此数据或如何正确释放NSFetchedResultsController
。
如果您需要更多信息,请随时提出。
答案 0 :(得分:2)
通常您不必担心Core Data中的内存管理。是的,在引擎盖下有一个缓存机制。
无论如何,有两种不同的方法来“解雇”记忆。
第一种是refreshObject:mergeChanges:
方法。传递给它NO
,它允许修剪对象图。换句话说,它会丢弃任何尚未保存到商店的已更改数据。
覆盖willTurnIntoFault
和didTurnIntoFault
以查看其实际效果。
另一种是在托管上下文上调用reset
。显然,这会删除上下文包含的所有对象。
希望有所帮助。
答案 1 :(得分:0)
你永远不应该自己调用dealloc,甚至不要自己调用dealloc。这是系统自己做的事情。