自从我两个月前搬到ARC以来,我发现我在释放物体时遇到了问题。 我现在正在使用吟唱来试图掌握如何做到这一点,但我有点挣扎。
我有一个计算NSManagedObject的函数。不幸的是,涉及到一些逻辑,所以我实际上需要获取对象(而不是仅仅计数)。
MOC正在主线程上运行,因此用于可见的所有内容。 计数发生在第一个视图(未读标记)上,并且对象本身未在该视图上使用(因此在计数后不再需要)
使用的功能如下:
- (int) getUnreadCount:(DOCategory*) category {
@autoreleasepool {
NSFetchedResultsController* items = [self getUnreadArticlesForCategory:category onlyForCounting:YES];
if([[items fetchedObjects] count] == 0) return 0;
int counter = 0;
long commonId = [[[[items fetchedObjects] objectAtIndex:0] commonId] longValue];
bool read = [[[[items fetchedObjects] objectAtIndex:0] read] boolValue];
for(DOArticle* article in [items fetchedObjects]){
long articleCommonId = [article.commonId longValue];
if(articleCommonId == commonId) {
//if([article.read boolValue] == true) read = true;
} else {
if (!read) {
counter++;
}
read = [article.read boolValue];
}
// If this was the last item, decide if an etra needs to be added
if([[items fetchedObjects] indexOfObject:article] == [[items fetchedObjects] count] - 1){
if(!read) {
counter++;
}
}
commonId = [[article commonId] longValue];
}
items = nil;
return counter;
}
}
这个函数叫做:
- (NSFetchedResultsController *) getUnreadArticlesForCategory:(DOCategory*) cat onlyForCounting:(bool) onlyForCounting {
NSPredicate* basePredicate = [NSPredicate predicateWithFormat:@"(((ANY groups.validTime > %@) && (ANY groups.active == YES)) || (ANY groups.universal == YES)) && (site.active == YES) && (removed == NO) && (language.enabled == YES)", [NSDate date]];
NSPredicate* countPredicate = [NSPredicate predicateWithFormat:@"(ANY categories.countUnread == YES)"];
NSPredicate* nonCountPredicate = [NSPredicate predicateWithFormat:@"(read == NO)"];
NSPredicate *predicate = nil;
NSPredicate* catPredicate = [NSPredicate predicateWithFormat:@"(ANY categories == %@)", cat];
if (onlyForCounting) {
predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
@[basePredicate, catPredicate, countPredicate]];
} else {
predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
@[basePredicate, catPredicate, nonCountPredicate]];
}
[NSFetchedResultsController deleteCacheWithName:_cacheName];
NSFetchedResultsController* aFetchedResultsController = [self createFetchedResultsController:_cacheName sectionString:nil sortBySection:NO];
[aFetchedResultsController.fetchRequest setPredicate:predicate];
[aFetchedResultsController.fetchRequest setFetchBatchSize:10];
[aFetchedResultsController.fetchRequest setFetchLimit:0];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"commonId" ascending:NO];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"language.order" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, sortDescriptor2, nil];
[aFetchedResultsController.fetchRequest setSortDescriptors:sortDescriptors];
NSError *fetchError;
if (![aFetchedResultsController performFetch:&fetchError]) {
NSLog(@"Fetching data error: %@", [fetchError localizedDescription]);
}
return aFetchedResultsController;
}
在乐器中我使用'Zombies'功能,并看到:
Graph Category Live Bytes # Living # Transient Overall Bytes # Overall Bytes Allocated (Net / Overall)
0 DOArticle_Article_ 10.88 KB 174 0 10.88 KB 174 <XRRatioObject: 0x7fe843844f20> %0.00, %0.00
查看它给出的一个对象:
# Event Type ∆ RefCt RefCt Timestamp Responsible Library Responsible Caller
0 Malloc +1 1 00:04.140.423 CoreData _PFAllocateObject
1 Retain +1 2 00:04.140.771 CoreData _faultBatchAtIndex
2 Retain +1 3 00:04.140.785 iDomsPortalDev -[DOArticleController getUnreadCount:]
3 Release -1 2 00:04.141.596 iDomsPortalDev -[DOArticleController getUnreadCount:]
4 Retain +1 3 00:04.141.599 iDomsPortalDev -[DOArticleController getUnreadCount:]
5 Release -1 2 00:04.141.614 iDomsPortalDev -[DOArticleController getUnreadCount:]
6 Release -1 1 00:04.156.411 CoreData _releaseStaleBatch
7 Release -1 0 00:04.298.640 CoreData -[_PFArray dealloc]
所以似乎应该释放该对象(因为我输入了@autorelease代码),但它仍然在'Allocations Summary'中说'生活',所以我不太确定该怎么做。如上所述,对象不再使用(或不应该使用),因此应该全部释放并消失。
答案 0 :(得分:1)
启用Zombies时,这不是默认行为吗?
启用僵尸检测后,即使零售额回零,对象也不会被破坏,因此也会保持活跃状态。那是因为僵尸功能特别用于检查过度释放对象的问题。
在其他情况下,我会禁用僵尸检测或仅使用“分配”(或“泄漏”)模板。这将为您提供有关实际内存使用情况,分配(以及生活/瞬态对象)的更准确信息。