【发布时间】:2013-11-29 20:55:13
【问题描述】:
自从两个月前我搬到 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;
}
在乐器中我使用“僵尸”功能,并看到:
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 代码),但它仍然在“分配摘要”中显示“活着”,所以我不太确定该怎么做。如前所述,这些对象不再使用(或不应该),因此应该全部释放并消失。
【问题讨论】:
标签: ios objective-c core-data automatic-ref-counting