2015-09-21 21 views
3

我需要上傳一些數據到服務器。在這樣做之前,我會獲取這個數據應該綁定到的一個實體(簡單關係)。如果沒有這樣的實體,我想創建它然後繼續上傳過程。但問題是,如果請求太多,所有請求最終都會比創建實體的速度快,因此會創建許多實體。解決方案是同步分派代碼塊,但在不同的線程上。我該怎麼做呢?如何在同一個不同的線程上用多個參數分派塊?

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^{ 
    PFQuery *query = [PFQuery queryWithClassName:@"FileOwner"]; 
    [query whereKey:@"identifier" equalTo:@"ABCDEFG"]; 
    PFObject *fileOwner = [query getFirstObject]; 
    if(fileOwner){ 
     [self continueUploadingData:data completionHandler:completionBlock]; 
    } 
    else{ 
     PFObject *newFileOwner = [PFObject objectWithClassName:@"FileOwner"]; 
     newPhotoOwner[@"identifier"] = @"ABCDEFG"; 
     [newPhotoOwner saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) { 
       if(succeeded)[self continueUploadingData:data completionHandler:completionBlock]; 
     }]; 
    } 
}); 

這個工作,但顯然阻止主線程。我不能使用detachSelector: toTarget: withObject:,因爲我有多個參數。

+0

爲什麼解決方案同步執行操作?對於異步方法,我有一個答案,但我知道你需要一個同步解決方案。另外,是否在塊的外部定義了'photoOwner'或者是否是拼寫錯誤? –

+0

@WilliamSmith。那麼,我對解決方案感興趣。不在解決方案本身。同步操作只是我的第一個想法,但它不是一個規則。所以我很高興看到你的建議。是的,那是「午夜」的錯字。對不起。 – efimovdk

回答

0

這裏有幫助的通用建議是用帶有完成塊的方法構建原子函數(比如解析的方法,也許就像你的continueUploading方法)。

在這種情況下,我們需要一個函數,將查找對象,返回它,如果它的發現,或創建並返回它,如果它沒有找到,所有的非同步...

- (void)findOrCreateFileOwnerWithIdentifier:(NSString *)identifier completion:(void (^)(PFObject *, NSError *))completion { 
    PFQuery *query = [PFQuery queryWithClassName:@"FileOwner"]; 
    [query whereKey:@"identifier" equalTo:identifier]; 
    [query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) { 
     if (object) { 
      return completion(object, nil); 
     } else { 
      PFObject *newFileOwner = [PFObject objectWithClassName:@"FileOwner"]; 
      newFileOwner[@"identifier"] = identifier; 
      [newFileOwner saveInBackgroundWithBlock:completion]; 
     } 
    }]; 
} 

現在,您可以說...

[self findOrCreateFileOwnerWithIdentifier:@"ABCDEFG" completion:^(PFObject *fileOwner, NSError *error) { 
    if (!error) { 
     [self continueUploadingData:data completionHandler:completionBlock]; 
    } else { 
     // handle error... probably pass it to completionBlock 
     // not shown because the OP code doesn't show how the block is declared 
    } 
}]; 
+0

謝謝。假設我在'for'循環中調用'findOrCreateFileOwnerWithIdentifier'。這種方法不會導致許多實體的相同問題,還是我錯過了某些東西? – efimovdk

+0

我不認爲你錯過了任何東西。在客戶端上,序列化操作的方法是在完成塊中啓動後續操作。對於任意多的數組,使用數組對它們進行參數化,然後讓調用方法從完成塊中遞歸調用它(將索引推進到數組中或截斷它)。使用解析的更好的答案是將任何你可以移動到雲代碼(a)承諾真正清理併發代碼(b)減少浪費的資源將中間結果移到客戶端。 – danh

相關問題