0

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

  1. 从 Facebook 拉帖子
  2. 通过创建一个名为 Post 的新托管对象、更新并保存它,将每个帖子保存到 Core Data
  3. 在处理每个帖子时,如果需要额外处理,我会将 post.obectID 添加到托管对象 IDS 的 NSMutableArray 中。这个 NSMutableArray 被另一个进程用来完成更新帖子。我正在使用对象 ID,因为单独的进程不会在同一个 tempContext 中,因此我将使用对象 ID 从核心数据中获取帖子。

该过程获取数据,我看到它存储在 store.data 中(我使用名为 Base 的产品来查看物理数据库文件的内容)。但是,我似乎无法存储帖子的对象 ID。正如您在代码中看到的,我正在使用 NSLog 打印出帖子的对象 ID,并且我看到了它们,因此我知道对象 ID 在那里。代码还显示我正在做 [tempContext save] 并且我正在做 [mainContext save:],因此我现在应该有永久的,而不是临时的帖子对象 ID。同样,数据在 Core data 的物理文件中,但可变数组计数仍然 = 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 --");
});

}

在此先感谢您的帮助!

4

1 回答 1

0

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

_postsNeedingPhotos = [[NSMutableArray alloc] init];

现在一切运行良好...... :)

于 2013-10-15T23:35:52.847 回答