2015-09-21 23 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

相关问题