我正在使用 GCD 以及核心数据。我知道 Core Data 不是线程安全的,所以我创建了以 mainContext 作为父级的子托管对象上下文(tempContext)。MainContext 有一个 PCS 来保存数据。我正在做的是:
- 从 Facebook 拉帖子
- 通过创建一个名为 Post 的新托管对象、更新并保存它,将每个帖子保存到 Core Data
- 在处理每个帖子时,如果需要额外处理,我会将 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 --");
});
}
在此先感谢您的帮助!