ios - 使用 ARC 释放 CoreData 对象

标签 ios objective-c core-data automatic-ref-counting

自从我两个月前搬到 ARC 后,我发现我在释放对象方面遇到了问题。 我现在正在使用安葬来尝试掌握如何做到这一点,但我有点挣扎。

我有一个计算 NSManagedObject 的函数。不幸的是,这涉及到一些逻辑,所以我实际上需要获取对象(而不仅仅是计数)。

MOC 在主线程上运行,因此用于可见的所有内容。 计数发生在第一个 View (未读角标(Badge))上,并且对象本身不用于该 View (因此在计数后不再需要)

使用的函数是这些:

- (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 代码),但它在“分配摘要”中仍然显示“活着”,所以我不太确定该怎么做。如前所述,对象不再(或不应)使用,因此应全部释放并消失。

最佳答案

这不是启用“僵尸”时的默认行为吗?

启用僵尸检测后,对象永远不会被破坏,因此即使保留计数回到零,对象也会保持事件状态。这是因为僵尸函数专门用于检查过度释放对象的问题。

在其他情况下,我会禁用僵尸检测或仅使用“分配”(或“泄漏”)模板。这将为您提供有关实际内存使用、分配(以及事件/ transient 对象)的更准确信息。

关于ios - 使用 ARC 释放 CoreData 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20018452/

相关文章:

ios - Core Data 和 UISearchBar 之间的问题

ios - 委托(delegate)仍然为零

objective-c - 是否可以从 NSData 或其他图像类型(CFImageRef、CIImage、UIImage)创建 ALAsset 对象?

ios - 联盟控制州

ios - UIImage CompressionQuality 不是线性的

arrays - 将从核心数据检索图像放入数组 swift

ios - 当用户在 UIWebView 中点击时,默认键盘是如何出现的?

ios - 单点触控 : pause application unit dialog response

iphone - 无法将 UITableViewCell didSelectRowAtIndexPath 数据传递给另一个 View Controller

c - 为什么在 Objective-C 的结构中使用函数指针?