2014-01-07 93 views
0

考慮下面的代碼:返回完成一個塊?

+(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僅之後執行newTag.tagId = tag.objectId回來了?

+0

您能否說一下'saveInBackgroundWithBlock?'核心數據中的線程安全性應該是一個問題。 –

+1

是否有任何理由以異步方式和背景保存? –

+0

密切相關:[塊內函數的返回值](http://stackoverflow.com/q/17642535) –

回答

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]; 
+0

@Allen你應該重新設計流程。我可以建議還是更新我的答案? – Mani

+0

是的請!只是想成爲一個更好的程序員:) – Allen

+0

@Allen我更新了我的代碼流。嘗試這個。 – Mani

0

您已經使用GCD異步,這意味着你在dispatch_async功能提供任務的塊將在另一個線程催生這樣的話你就不用管了,當將完成並返回。

但是,在成功保存核心數據中的對象後,您可以通過從衍生線程訪問主線程來異步返回到newTag對象。 爲此你必須閱讀更多關於GCD的信息。 從閱讀official docs開始總是更好。