当应用程序被推送到后台时,NSManagedObjectContext不会获取或保存对象

时间:2014-07-08 12:48:13

标签: iphone core-data background nsmanagedobjectcontext nsoperationqueue

在我的应用程序中,我有一个父子项上下文被删除。将对象保存到处理自身的核心数据时,可以在 dispatch_async 中完成。在前台一切正常,但当应用程序被推送到后台时,抓取请求和保存操作被阻止。我也使用 NSOperationQueue 来排队我的操作。在前景中,所有操作都运行良好内存使用情况稳定,但是当推到后台时,即使内存消耗量增加,内存压力下应用程序也会崩溃。

- (void) saveDocument:(ALEXDocument*)document forDownloaded:(BOOL)isDownloadCompleted
{

    BOOL checkWithKillDocId = NO;
    if(!document.tocId || [document.tocId isEqualToString:@""])
        document.tocId = nil;

    NSManagedObjectContext *context = [self getNewPrivateManagedObjectContext];

    NSFetchRequest *request         = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity     = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:context];
    [request setEntity:entity];

    NSPredicate *predicate;

    if (![document.killDocId isEqual:[NSNull null]] && document.killDocId!= nil)
    {
        if(![document.killDocId isEqualToString:@"(null)"] && ![document.killDocId isEqualToString:@""])
        {
            predicate = [NSPredicate predicateWithFormat:@"killDocId = %@",document.killDocId];
            checkWithKillDocId = YES;
        }
        else
        {
            predicate                       = [ NSPredicate predicateWithFormat:@"reference == %@ AND section = %d AND tocRelation.tocId = %@ ", document.reference,document.section,document.tocId];
            checkWithKillDocId = NO;
        }

    }
    else
    {
         predicate                       = [ NSPredicate predicateWithFormat:@"reference == %@ AND section = %d AND tocRelation.tocId = %@ ", document.reference,document.section,document.tocId];
        checkWithKillDocId = NO;
    }

    [request setPredicate:predicate];

    NSError *error;

    Document *coreDataDoc          = (Document*)[[context executeFetchRequest:request error:&error] lastObject];
    NSLog(@"Document");
    if (!coreDataDoc || coreDataDoc == nil)
    {
        if(checkWithKillDocId)
        {
            predicate                       = [ NSPredicate predicateWithFormat:@"reference == %@ AND section = %d AND tocRelation.tocId = %@ ", document.reference,document.section,document.tocId];
            [request setPredicate:predicate];
            coreDataDoc          = (Document*)[[context executeFetchRequest:request error:&error] lastObject];
            if (!coreDataDoc || coreDataDoc == nil)
            {
                coreDataDoc = [NSEntityDescription insertNewObjectForEntityForName:@"Document" inManagedObjectContext:context];
            }
        }
        else
        {
             coreDataDoc = [NSEntityDescription insertNewObjectForEntityForName:@"Document" inManagedObjectContext:context];
        }

    }

    coreDataDoc.anchorName          = document.anchorName;
    coreDataDoc.binary              = document.binary;
    coreDataDoc.contentSize         = [NSNumber numberWithInt:document.contentSize];
    coreDataDoc.copyright           = document.copyright;
    coreDataDoc.createdDate         = document.date;
    coreDataDoc.domain              = document.domain;
    coreDataDoc.fileName            = document.fileName;
    coreDataDoc.htmlContent         = document.htmlContent;
    coreDataDoc.mimeType            = document.mimeType;
    coreDataDoc.reference           = document.reference;
    coreDataDoc.section             = [NSNumber numberWithInteger:document.section];
    coreDataDoc.source              = document.source;
    coreDataDoc.title               = document.title;

    coreDataDoc.tocReference        = document.tocReference;
    coreDataDoc.nextReference       = document.nextReference;
    coreDataDoc.nextSection         = [NSString stringWithFormat:@"%@",document.nextSection];
    coreDataDoc.previousReference   = document.previousReference;
    coreDataDoc.previousSection     = [NSString stringWithFormat:@"%@",document.previousSection];
    coreDataDoc.downloadedDate      = [NSDate date];
    coreDataDoc.status              = document.documentStatus;
    coreDataDoc.killDocId           = document.killDocId;
    [self dbSaveInContext:context];
//    context = nil;
//    coreDataDoc = nil;
//    [context reset];
//    [context refreshObject:coreDataDoc mergeChanges:NO];
    NSLog(@"Context");

}

1 个答案:

答案 0 :(得分:0)

要在后台运行任何流程,您需要告诉iOS您的应用将继续并完成任务。

UIBackgroundTaskIdentifier backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    NSLog(@"Not running background tasks anymore.");
    [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
    backgroundTask = UIBackgroundTaskInvalid;
}];

它可以让您在短时间内在后台运行任何任务。 (10分钟到5秒)。