无法将管理对象ID添加到具有子管理对象子上下文的GCD中的NSMutableArray

时间:2013-10-15 20:38:50

标签: ios core-data grand-central-dispatch nsmanagedobject nsmanagedobjectid

我正在使用GCD以及核心数据。我知道Core Data不是线程安全的,所以我用mainContext作为父创建子管理对象上下文(tempContext)。 MainContext有一个PCS来保存数据。我正在做的是:

  1. 从Facebook上拉帖子
  2. 通过创建名为Post的新托管对象,更新并保存每个帖子,将每个帖子保存到Core Data
  3. 当我处理每个帖子时,如果需要额外的处理,我将post.obectID添加到托管对象IDS的NSMutableArray。此NSMutableArray由另一个进程用于完成更新帖子。我正在使用对象ID,因为单独的进程不会在同一个tempContext中,因此我将使用对象ID从核心数据中获取帖子。
  4. 进程获取数据,我看到它存储在store.data中(我使用名为Base的产品来查看物理数据库文件的内容)。但是,我似乎无法存储帖子的对象ID。正如您在代码中看到的,我使用NSLog打印出帖子的对象ID,我看到它们,因此我知道对象ID在那里。代码还显示我正在做[tempContext save],我正在做[mainContext save:],因此我现在应该为帖子提供永久的,而不是临时的对象ID。同样,数据在Core数据的物理文件中,但可变数组计数仍然是= 0.

    将对象ID保存到NSMutableArray我做错了什么?在代码中你会看到我已经尝试在主队列中尝试运行[mutableArray addObject:p.objectID],但这没关系。

    这是我的代码:

    - (void)processPosts {
    
    NSLog(@"-- Begin processPosts --");
    
    dispatch_async(_processPostsQ, ^{
    
        for (NSDictionary * info in _posts)
        {
            NSManagedObjectContext * tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
            tempContext.parentContext = mainMOContext;
    
            // If Post exists, rewrite over top of it. otherwise create a new one
            NSFetchRequest      * fetchRequest = [[NSFetchRequest alloc] init];
            NSEntityDescription * entity       = [[mainMOModel entitiesByName] objectForKey:@"Post"];
    
            [fetchRequest setEntity:entity];
    
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"fb_post_id = %@",
                                      [info objectForKey:@"post_id"]];
    
            [fetchRequest setPredicate:predicate];
    
            NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"fb_post_id" ascending:YES];
            [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sd]];
    
            NSError * error = nil;
            NSArray * fetchResults = [tempContext executeFetchRequest:fetchRequest error:&error];
    
            Post * p = [NSEntityDescription insertNewObjectForEntityForName:@"Post" inManagedObjectContext:tempContext];
    
            if (fetchResults.count > 0)
            {
                p = [fetchResults objectAtIndex:0];
            }
    
            NSDictionary * appData = [[NSDictionary alloc]init];
            appData = [info objectForKey:@"app_data"];
    
            p.fb_actor_id       = [info objectForKey:@"actor_id"];
            p.fb_app_data       = [self archivedData:[info objectForKey:@"app_data"]];
            p.fb_attachment     = [self archivedData:[info objectForKey:@"attachment"]];
            p.fb_created_time   = [info objectForKey:@"created_time"];
            p.timestamp         = [info objectForKey:@"updated_time"];
            p.fb_attribution    = NULL_TO_NIL([info objectForKey:@"attribution"]);
            p.fb_message        = NULL_TO_NIL([info objectForKey:@"message"]);
            p.fb_type           = NULL_TO_NIL([info objectForKey:@"type"]);
            p.fb_post_id        = [info objectForKey:@"post_id"];
            p.fb_likes_info     = [self archivedData:[info objectForKey:@"like_info"]];
            p.fb_comments_info  = [self archivedData:[info objectForKey:@"comment_info"]];
            p.fb_parent_post_id = NULL_TO_NIL([info objectForKey:@"parent_post_id"]);
            p.fb_permalink      = NULL_TO_NIL([info objectForKey:@"permalink"]);
            p.fb_photo_data     = nil;
            p.fb_place          = NULL_TO_NIL([info objectForKey:@"places"]);
            p.fb_source_id      = [info objectForKey:@"source_id"];
            p.social_network    = @"facebook";
            p.fkPostToFriend    = [[FriendStore sharedStore]findFriendWithFBUID:[info objectForKey:@"source_id"] withMOContext:tempContext];
    
            [tempContext save:&error];
    
            dispatch_async(dispatch_get_main_queue(), ^{
                NSError * error;
                [mainMOContext save:&error];
            });
    
    
            if (appData.count > 0)
            {
                if ([[appData objectForKey:@"photo_ids"] count] > 0)
                {
                    NSLog(@"   -- photos need to be loaded for postID: %@",p.objectID);
                    //dispatch_async(dispatch_get_main_queue(), ^{
                        [_postsNeedingPhotos addObject:p.objectID];
                    //});
                }
            }
        }
    
        NSLog(@"ProcessPosts: num of posts needing photos: %d",_postsNeedingPhotos.count);
        dispatch_async(_getPhotosQ, ^{
            [self loadPhotoData];
        });
        NSLog(@"-- End processPosts --");
    });
    

    }

    提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我是个白痴。我忘了用以下内容初始化_postsNeedingPhotos:

_postsNeedingPhotos = [[NSMutableArray alloc] init];

现在一切正常......:)

相关问题