给出以下代码:
+(Tag *) addNewTagwithName:(NSString *)tagName Error:(NSError **)addError {
AppDelegate *delegate = (AppDelegate *) [[UIApplication sharedApplication]delegate];
Tag *newTag = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:delegate.managedObjectContext];
newTag.tagName = tagName;
//no error save to parse
PFObject *tag = [PFObject objectWithClassName:@"Tag"];
tag[@"tagName"] = newTag.tagName;
[tag saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if(error) {
*addError = error;
} else {
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error = nil;
newTag.tagId = tag.objectId;
if(![delegate.managedObjectContext save:&error]) {
*addError = error;
}
});
}
}];
return newTag;
}
在执行newTag.tagId = tag.objectId之后,有哪些方法可以确保只返回newTag?
答案 0 :(得分:1)
这是不可能的。因为addNewTagwithName:
方法立即返回,但是完成块将在稍后执行,并且它不会发生任何事情。
<强>更新强> 请尝试以下代码...
+(void) addNewTagwithName:(NSString *)tagName Error:(NSError **)addError completionBlock:(CompletionBlock)comBlock {
//no error save to parse
PFObject *tag = [PFObject objectWithClassName:@"Tag"];
tag[@"tagName"] = tagName;
[tag saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if(error) {
*addError = error;
} else {
dispatch_async(dispatch_get_main_queue(), ^{
comBlock(succeeded,error);
if(![delegate.managedObjectContext save:&error]) {
*addError = error;
}
});
}
}];
}
你的方法调用应该是。
CompletionBlock currentTagBlock = ^(BOOL succeeded, NSError *error){
AppDelegate *delegate = (AppDelegate *) [[UIApplication sharedApplication]delegate];
Tag *newTag = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:delegate.managedObjectContext];
newTag.tagName = tagName;
if(!error);
newTag.tagId = tag.objectId;
/* Here you should write your code using tag
ex: [self processWithNewTag:newTag]; */
};
[Tag addNewTagwithName:tagName Error:&addError completionBlock:currentTagBlock];
答案 1 :(得分:0)
您已异步使用GCD,这意味着您在dispatch_async函数中提供的任务块将在另一个线程上生成,因此您无法控制何时完成并返回。
但是,在核心数据中成功保存对象后,通过从生成的线程访问主线程,可以异步返回newTag对象。 为此,您必须阅读有关GCD的更多信息。 从阅读official docs开始总是更好。