调用Core Data Operation时出现“无法及时更新场景”消息

时间:2015-07-16 11:22:36

标签: ios objective-c multithreading core-data

我面临一个奇怪的问题“未及时更新场景”。下载数据后,我将其存储到Core Data中。如果应用程序在前台,一切都会正常工作。我只是在将状态,背景和前景之间的应用程序连续切换到核心数据的过程中才会出现此崩溃。在调试模式下不会发生此崩溃。

我尝试将日志放在Core Data操作方法的不同阶段,我发现应用程序实际崩溃的点。在UI中,我使用以下代码

DatabaseManagerClass *database = [[DatabaseManagerClass alloc]init];
[database deleteDataFromFormTable:nil];

[database insertDataInChecklistTable:[self.responseDictionary valueForKey:@"checklists"]];

[self performSelectorOnMainThread:@selector(mainThreadTask) withObject:nil waitUntilDone:YES];`

崩溃发生在方法“insertDataInChecklistTable”中。我检查了insertDataInChecklistTable正在工作的线程。它只在主线程中。任何人都可以提出一些建议来解决这个问题。

提前致谢, SREE。

带执行块的更新代码

-(void)insertDataInFormColumnsTable:(NSMutableArray*)responseArray withForm:(Form*)form

{     AppDelegate objAppDelegate =(AppDelegate )[[UIApplication sharedApplication] delegate];

NSManagedObjectContext *moc   = [objAppDelegate managedObjectContext];
NSManagedObjectContext *bgMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

[bgMOC performBlock:^{
    for (int count=0; count<[responseArray count]; count++)
    {
        NSDictionary *columnDict = [responseArray objectAtIndex:count];

        Form_Column *formColumn = [NSEntityDescription insertNewObjectForEntityForName:@"Form_Column" inManagedObjectContext:moc];


        if ([columnDict valueForKey:FORMULA]!=[NSNull null])        //Added by mritunjay
            formColumn.formula = [columnDict valueForKey:FORMULA];
        else
            formColumn.formula=nil;

        if ([columnDict valueForKey:ASP_EDITABLE]!=[NSNull null])
            formColumn.asp_editable = [columnDict valueForKey:ASP_EDITABLE];
        else
            formColumn.asp_editable=nil;


        if ([columnDict valueForKey:CM_EDITABLE]!=[NSNull null])
            formColumn.cm_editable = [columnDict valueForKey:CM_EDITABLE];
        else
            formColumn.cm_editable=nil;

        if ([columnDict valueForKey:IM_EDITABLE]!=[NSNull null])
            formColumn.im_editable = [columnDict valueForKey:IM_EDITABLE];
        else
            formColumn.im_editable=nil;


        if ([columnDict valueForKey:SP_EDITABLE]!=[NSNull null])
            formColumn.sp_editable = [columnDict valueForKey:SP_EDITABLE];
        else
            formColumn.sp_editable=nil;

        if ([columnDict valueForKey:ASP_EDITABLE]!=[NSNull null])
            formColumn.dialog_row = [columnDict valueForKey:ASP_EDITABLE];
        else
            formColumn.dialog_row=nil;

        if ([columnDict valueForKey:INDEX]!=[NSNull null])
            formColumn.index = [columnDict valueForKey:INDEX];
        else
            formColumn.index=nil;

        if ([columnDict valueForKey:WEB_ONLY]!=[NSNull null])
            formColumn.web_only = [columnDict valueForKey:WEB_ONLY];
        else
            formColumn.web_only=nil;

        if ([columnDict valueForKey:LABEL]!=[NSNull null])
            formColumn.label = [columnDict valueForKey:LABEL];
        else
            formColumn.label=nil;

        formColumn.form_id = form.form_id;

        if ([columnDict valueForKey:ID]!=[NSNull null])
            formColumn.column_id=[columnDict valueForKey:ID];
        else
            formColumn.column_id=nil;

        if ([columnDict valueForKey:TYPE]!=[NSNull null])
            formColumn.type=[columnDict valueForKey:TYPE];
        else
            formColumn.type=nil;

        NSArray *selectionArray = [columnDict valueForKey:SELECTIONS];

        if ([selectionArray count]) {


            for (int count = 0; count < [selectionArray count]; count++)
            {
                Form_Sub_Columns *formSubColumns = [NSEntityDescription insertNewObjectForEntityForName:@"Form_Sub_Columns" inManagedObjectContext:moc];

                NSDictionary *subColumnDict = [selectionArray objectAtIndex:count];

                if ([subColumnDict valueForKey:ID]!=[NSNull null])
                    formSubColumns.column_id=[subColumnDict valueForKey:ID];
                else
                    formSubColumns.column_id=nil;

                if ([subColumnDict valueForKey:LABEL]!=[NSNull null])
                    formSubColumns.label=[subColumnDict valueForKey:LABEL];
                else
                    formSubColumns.label=nil;

                if ([subColumnDict valueForKey:REQUIRES_REMARKS]!=[NSNull null])
                    formSubColumns.requires_remarks=[subColumnDict valueForKey:REQUIRES_REMARKS];
                else
                    formSubColumns.requires_remarks=nil;


                if ([subColumnDict valueForKey:VALUE]!=[NSNull null])
                    formSubColumns.value=[subColumnDict valueForKey:VALUE];
                else
                    formSubColumns.value=nil;


                if ([subColumnDict valueForKey:DESCRIPTION]!=[NSNull null])
                    formSubColumns.description_name=[subColumnDict valueForKey:DESCRIPTION];
                else
                    formSubColumns.description_name=nil;



                if ([subColumnDict valueForKey:SELECTION_TYPE_ID]!=[NSNull null])
                    formSubColumns.selection_type_id=[subColumnDict valueForKey:SELECTION_TYPE_ID];
                else
                    formSubColumns.value=nil;

                [formColumn addSun_columnsObject:formSubColumns];
            }
        }
        [formColumn addFormObject:form];

        [form addColumnsObject:formColumn];

    }

    if([form.enable_attachment boolValue])
    {
        Form_Column *formColumn = [NSEntityDescription insertNewObjectForEntityForName:@"Form_Column" inManagedObjectContext:moc];

        formColumn.label = @"Add Attachments";

        formColumn.form_id = form.form_id;
        formColumn.index = [NSNumber numberWithInt:998];
        formColumn.column_id=[NSNumber numberWithInt:998];    // hardcoded if Attachment is Enabled.
        formColumn.web_only = [NSNumber numberWithInt:0];
        formColumn.type=[NSNumber numberWithInt:-1];

        [form addColumnsObject:formColumn];

    }

    if ([[NSThread currentThread] isMainThread]) {
        NSLog(@"Main Thread inside block");
    }
    else {
        NSLog(@"Not main thread inside block");
    }

    NSError *error;

    if(![bgMOC save:&error]){
        NSLog(@"Error %@", [error localizedDescription]);
    }
}];

}

1 个答案:

答案 0 :(得分:1)

处理主/用户界线上的数据总是是一个坏主意,并导致这样的问题。

您的var url = 'https://accounts.google.com/o/oauth2/token'; var payload = { grant_type: 'authorization_code', code: authResult['code'], client_id: clientID, client_secret: clientSecret, redirect_uri: '', dataType: 'jsonp' }; $.post(url, { form: payload }, function(error, response, body) { console.log(body); }); 需要在后台队列上运行,这意味着您应该:

  1. 创建第二个-insertDataIntoChecklistTable,即NSManagedObjectContext
  2. 将其与您的主要背景相关联
  3. 使用NSPrivateQueueConcurrencyType处理针对该-performBlock:
  4. 的数据
  5. 处理完成后保存
  6. 这将使您的数据处理脱离主队列。永远不要在主队列上处理数据。