Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios dispatch\u async和async请求出现问题_Ios_Multithreading_Asynchronous_Grand Central Dispatch - Fatal编程技术网

Ios dispatch\u async和async请求出现问题

Ios dispatch\u async和async请求出现问题,ios,multithreading,asynchronous,grand-central-dispatch,Ios,Multithreading,Asynchronous,Grand Central Dispatch,因此,第一个问题是dispatch\u async如何确定使用哪个线程?随便挑?我需要做一些解析和核心数据的工作,所以我不想阻塞UI线程并使用dispatch\u async,但在那之后,我发送一个NSURLRequest,以获取更多的数据,回调永远不会被调用(可能是因为线程已经死了) 那么什么是制作它的好方法呢?我不能用 sendAsynchronousRequest:queue:completionHandler: 因为部署操作系统是4。现在我只是把请求发送到内部 dispatch_as

因此,第一个问题是
dispatch\u async
如何确定使用哪个线程?随便挑?我需要做一些解析和核心数据的工作,所以我不想阻塞UI线程并使用
dispatch\u async
,但在那之后,我发送一个
NSURLRequest
,以获取更多的数据,回调永远不会被调用(可能是因为线程已经死了)

那么什么是制作它的好方法呢?我不能用

sendAsynchronousRequest:queue:completionHandler: 
因为部署操作系统是4。现在我只是把请求发送到内部

dispatch_async(dispatch_get_main_queue(), ^{
});

它位于
dispatch\u async(myQueue)
块中,该块完成对核心数据的所有解析和保存。但对我来说这似乎并不正确,我的意思是应该有一种方法使用dispatch\u async并告诉它不要扼杀趋势,对吗?因为使用同步请求不是一个选项。

当您在块内使用
sendAsynchronousRequest:…
时,块将在触发异步请求回调之前终止

既然您已经在后台线程中,那么在该线程中使用同步方法来获取数据怎么样?
+[NSURLRequest sendSynchronousRequest:returningResponse:error:
,或者更简单的方法,
+[NSData dataWithContentsOfURL:

您可以在后台线程上运行的块内调用这些函数,在调用完成之前,该块不会前进。然后,您可以通过回拨到主队列来更新UI:

dispatch_async(yourQueue, ^{
    // Do some stuff

    NSData * fetchedData = [NSData dataWithContentsOfURL: someURL];

    // Do some more stuff with the data

    dispatch_async(dispatch_get_main_queue(), ^{
       // Do some stuff on the main queue
    }
});
因此,第一个问题是dispatch_async如何确定使用哪个线程

在使用GCD时,不应该考虑线程。这些都是你在幕后处理的。您在队列中思考,这是您传递给
dispatch\u async
以及要执行的块的内容。GCD队列在某种程度上映射到一个线程,但您不必担心幕后发生了什么-GCD将为您处理所有这些

至于您的代码,我假设它看起来与此类似:

dispatch_async(myQueue, ^{
    // Do some stuff off the main queue

    dispatch_async(dispatch_get_main_queue(), ^{ 
        // Do something with the UI
    });
});
这一点都没有错。您不必担心发送到
myQueue
的块所运行的线程可能会终止。队列将一直保留,直到块完成运行。您可以在原始调度中调度到主队列上,这一事实很好——主队列上的工作可以很好地运行

我想您也在问,为什么在异步调度中使用
NSURLRequest
时,您会发现它从未调用回调。这将是因为它与当前运行循环紧密耦合,并且如果您当前在后台线程上(您的
myQueue
将在其上运行),那么在队列上放置另一个块之前,该运行循环不会再次运行。所以你的回调永远不会运行


我鼓励您去阅读更多关于GCD的内容,以及异步与同步的实际含义,因为我觉得您可能还没有完全理解它。我回答了一个类似的问题。

你是对的,问题是线程已经死了,因为NSURLConnection在它的生命周期内不会让它保持活动状态。连接返回时将被丢弃。 您可以使用一些黑魔法明确地保持线程的活动状态;)完成后释放线程。在这种情况下,成功或出错时将_isFinishedLoading设置为true

所以在这种情况下,在使用块时不关心线程是不正确的,因为NSURLConnection并不真正兼容。但是,块非常有用,因为框架根据底层硬件和可用资源为您选择最佳线程

NSURLConnection* connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
[connection start];
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
_isFinishedLoading = NO;
while (!_isFinishedLoading)
{
    [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}

但我担心的是(从GCD引用中)“函数在块完成之前不会返回。调用此函数并以当前队列为目标会导致死锁。”并且此代码将执行多次。我收到了一个带有20个ID的响应,然后我为每个ID发送了一个请求,所以如果服务器不可用,比如说呢?线程将被阻塞。。我习惯于认为使用任何同步请求都不是一个好主意,所以我的问题是,如果我创建了很多包含同步网络请求的dispatch\u async-s,那么我会耗尽线程吗?
dispatch\u async
!=新线程。一个新队列可能意味着一个新线程,但它可能不是。跟我重复:“我不必担心线程,GCD会为我处理它。”:-)。因此,基本上,如果您将async分派到同一队列上,那么这些队列将一个接一个地运行(除非它是并行队列)。有关这方面的更多信息,请参阅我在回答末尾链接的帖子。因此,可以肯定的是,在dispatch_async中调用同步请求完全可以吗?(除了不能取消的事实外)只要您没有将分派到与
分派\u async
相同的队列上就可以了,这应该是相当明显的。同步意味着对
dispatch\u sync
的调用在您分派的块完成之前不会返回,而在外部块返回=deadlock之前,该块无法运行。