在完成一个区块后返回?

时间:2014-01-07 06:19:51

标签: ios objective-c core-data objective-c-blocks

给出以下代码:

+(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?

2 个答案:

答案 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开始总是更好。