【问题标题】:Return a dispatch_async fetched variable [duplicate]返回一个 dispatch_async 获取的变量 [重复]
【发布时间】:2013-11-24 22:08:12
【问题描述】:

基本上:一个方法需要返回一个在 dispatch_async 中获取的 NSDictionary。这是我尝试过的:

- (NSDictionary *)fetchNSDictionary {
    dispatch_queue_t Queue = dispatch_queue_create("Dictionary fetcher", NULL);
    dispatch_async(Queue, ^{
        NSDictionary *dict = ...
        dispatch_async(dispatch_get_main_queue(),^{
            return dict;
        )};
    )};
}

结果:

Incompatible block pointer types passing 'NSDictionary *(^)(void)' 
to parameter of type 'dispatch_block_t' (aka 'void (^)(void)')

有什么想法吗?

【问题讨论】:

  • 严格来说,不能满足“方法需要返回一个在 dispatch_async 中获取的 NSDictionary”的要求。当方法返回时,根据异步的定义,结果尚未评估。因此,您无法获得返回的结果,除非您强制该方法变为同步 - 但是这是一种“反模式”、“代码异味”、不好的做法以及其他不太好的事情;)
  • 我的鼻子被堵住了,所以直到 Undo 的回答我才意识到这个概念有多糟糕。

标签: ios objective-c multithreading objective-c-blocks


【解决方案1】:

当您说return dict; 时,您实际上是在尝试将dict 返回给调度块的调用者(运行后台异步的自动化进程)——这是行不通的。

由于您使用的是异步方法,因此您无法将在块中接收到的数据返回给您开始网络操作的方法。当该块中的代码被调用时,系统已经完成了很长时间的执行那个方法。

您需要做的是设置一个委托系统 - 如果这是一个帮助器类,您可以添加一个协议,包括像 didFinishLoadingStuff:(NSDictionary *)stuff 这样的方法。

你会改变

 - (NSData *) fetchNSDictionary{...}

类似

- (void)getDictionaryWithDelegate:(NSObject<StuffGetterProtocol> *)delegate{...}

而不是return dict;,你会说:

[delegate didFinishLoadingStuff:dict];

当然,在你调用它的任何类中实现委托方法:

- (void)didFinishLoadingStuff:(NSDictionary *)stuff
{
    //do something with stuff
}

【讨论】:

  • 由于他已经在使用块,我建议将他的回调放入块中。你的方法确实有道理,但如果他只需要一次,我认为这太混乱了;)
猜你喜欢
  • 1970-01-01
  • 2021-02-28
  • 2013-11-13
  • 2018-05-30
  • 1970-01-01
  • 2019-11-19
  • 2015-11-27
  • 2017-09-04
  • 1970-01-01
相关资源
最近更新 更多