ios 与多线程相比,Objective-C 中的同步和异步调用有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21122842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:07:20  来源:igfitidea点击:

What's the difference between synchronous and asynchronous calls in Objective-C, versus multi-threading?

iosobjective-cmultithreadingasynchronousgrand-central-dispatch

提问by Doug Smith

For the longest time I thought asynchronous was synonymous to running something on a background thread, while synchronous meant on the main thread (blocking UI updates and interactions). I understand that not running on the main thread for expensive actions is because it doesn't allow UI actions to occur as the main thread is occupied, but why is synchronous troublesome?

长期以来,我认为异步是在后台线程上运行某些东西的同义词,而同步则是在主线程上运行(阻止 UI 更新和交互)。我知道不运行在主线程上进行昂贵的操作是因为它不允许在主线程被占用时发生 UI 操作,但是为什么同步很麻烦?

However, it's since came to my attention that you can make asynchronous calls on the main thread, and synchronous calls on background threads.

但是,我注意到您可以在主线程上进行异步调用,而在后台线程上进行同步调用。

I always hear people saying not to use expensive calls synchronously or on the main thread, as it will block the UI for the user. Are these two separate issues I should be making sure I don't do? What are the differences?

我总是听到人们说不要同步或在主线程上使用昂贵的调用,因为它会阻塞用户的 UI。这两个单独的问题是我应该确保不这样做的吗?有什么区别?

回答by Rob

When you invoke something synchronously, it means that the thread that initiated that operation will wait for the task to finish before continuing. Asynchronous means that it will not wait.

当您同步调用某些内容时,这意味着启动该操作的线程将等待任务完成后再继续。异步意味着它不会等待。

Having said that, when people suggest that you perform some slow or expensive process asynchronously, they are implicitly suggesting not only that you should run it asynchronously, but that you should do that on a background thread. The goal is to free the main thread so that it can continue to respond to the user interface (rather than freezing), so you are dispatching tasks to a background thread asynchronously.

话虽如此,当人们建议您异步执行一些缓慢或昂贵的过程时,他们暗示不仅应该异步运行它,而且还应该在后台线程上执行此操作。目标是释放主线程,以便它可以继续响应用户界面(而不是冻结),因此您将任务异步分派到后台线程。

So, there are two parts to that. First, using GCD as an example, you grab a background queue (either grab one of the global background queues, or create your own):

所以,有两个部分。首先,以 GCD 为例,你抓取一个后台队列(要么抓取一个全局后台队列,要么创建自己的):

// one of the global concurrent background queues

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// or you could create your own serial background queue:
//
// dispatch_queue_t queue = dispatch_queue_create("com.domain.app.queuename", 0);

Second, you dispatch your tasks to that queue asynchronously:

其次,您将任务异步分派到该队列:

dispatch_async(queue, ^{
    // the slow stuff to be done in the background
});

The pattern for operation queues is very similar. Create an operation queue and add operations to that queue.

操作队列的模式非常相似。创建一个操作队列并将操作添加到该队列。

In reality, the synchronous vs asynchronous distinction is completely different from the main queue vs background queue distinction. But when people talk about "run some slow process asynchronously", they're really saying "run some slow process asynchronously on a background queue."

实际上,同步与异步的区别与主队列与后台队列的区别完全不同。但是当人们谈论“异步运行一些慢速进程”时,他们实际上是在说“在后台队列上异步运行一些慢速进程”。

回答by Chuck

"Synchronous"essentially means "in order."Basically, when you do a synchronous operation, everything that comes later has to wait for the operation to finish before they can start.

“同步”本质上意味着“按顺序”。基本上,当您执行同步操作时,后面的所有操作都必须等待操作完成才能开始。

Conversely, "asynchronous"more or less means "not in order."When you do something asynchronously, the following code can immediately run and the asynchronous operation will be run…sometime. It might be run in parallel with the rest of the code on another thread. It might simply be scheduled for some other time on the same thread.

相反,“异步”或多或少意味着“无序”。当您异步执行某些操作时,以下代码可以立即运行,并且异步操作将在某个时间运行。它可能与另一个线程上的其余代码并行运行。它可能只是被安排在同一线程上的其他时间。

The concept of synchronicity doesn't have anything to do with particular threads, per se. It's just about whether you have to wait for an operation to finish or not.

同步性的概念本身与特定线程没有任何关系。这只是关于您是否必须等待操作完成。

Where the main thread comes into this in a big way is in Cocoa (Touch) programs. The AppKit runs the main event loop on the main thread, so if the main thread is waiting for an operation to complete, it can't process any input or update the UI. If you have a piece of code running on a background thread, though, running synchronous code will not block the main event loop, because it isn't the main thread that's waiting for the synchronous operation to complete.

主要线程在 Cocoa (Touch) 程序中的作用很大。AppKit 在主线程上运行主事件循环,因此如果主线程正在等待操作完成,它无法处理任何输入或更新 UI。但是,如果您有一段代码在后台线程上运行,则运行同步代码不会阻塞主事件循环,因为等待同步操作完成的不是主线程。

Similarly, a long-running asynchronous operation from a background thread that you place on the main thread cancause problems, because while the background thread isn't going to wait for the operation to complete, it is still taking up time on the main thread where the event loop needs to run.

类似地,来自您放置在主线程上的后台线程的长时间运行的异步操作可能会导致问题,因为虽然后台线程不会等待操作完成,但它仍会占用主线程上的时间事件循环需要运行的地方。

回答by Kunal Balani

Lets us take some easy examples :

让我们举一些简单的例子:

Asynchronous call with multithreading :

多线程异步调用:

// Methods gets called in different thread and does not block the current thread. 
[NSURLConnection sendAsynchronousRequest:request 
                                   queue:queue 
                       completionHandler:
    ^(NSURLResponse *response, NSData *data, NSError *error) {
}];

Synchronous call with multithreading:

多线程同步调用:

//Do something
dispatch_sync(queue, ^{
    //Do something else
});
//Do More Stuff

Here you got //Do something //Do something else and //Do More stuff done consecutively even though //Do something else is done on a different thread.

在这里你得到了 //Do something //Do something else 和 //Do More stuff 连续完成,即使 //Do something 在不同的线程上完成。

Usually, when people use different thread, the whole purpose is so that something can get executed without waiting. Say you want to download large amount of data but you want to keep the UI smooth.

通常,当人们使用不同的线程时,整个目的是让某些事情无需等待即可执行。假设您想下载大量数据,但又想保持 UI 流畅。

Hence, dispatch_sync is rarely used. But it's there. I personally never used that. Why not ask for some sample code or project that does use dispatch_sync.

因此,很少使用 dispatch_sync。但它就在那里。我个人从未使用过。为什么不要求一些使用 dispatch_sync 的示例代码或项目。

Asynchronous call with one thread :

一个线程的异步调用:

[self performSelector:@selector(doSomething) withObject:nil afterDelay:0];

Here current runloop to complete before 'doSomething' is called. In other words, the current call stack can be completed (the current method returns) before 'doSomething' is called.

这里当前的 runloop 在调用 'doSomething' 之前完成。换句话说,可以在调用 'doSomething' 之前完成当前调用堆栈(当前方法返回)。

Synchronous call with one thread:

一个线程同步调用:

 [self doSomething];

I don't think you need explanation for this.

我认为你不需要对此进行解释。

In general asynchronous activity is not same as threading , however in iOS they are implemented using the this fashion. Its not true for all languages. We usually manage different asynchronous task using run loops.

一般来说,异步活动与线程不同,但是在 iOS 中它们是使用这种方式实现的。并非适用于所有语言。我们通常使用运行循环来管理不同的异步任务。

回答by Akbar Khan

swift 3, 4, 4,2Synchronousmeans that thread that initiated that operation will wait for the task to finish before continuing.

swift 3, 4, 4,2 Synchronous意味着启动该操作的线程将等待任务完成后再继续。

DispatchQueue.main.sync {

}

Asynchronousmeans that Completes a task in background and can notify you when complete means it will not wait.

异步意味着在后台完成任务并且可以在完成时通知您意味着它不会等待。

DispatchQueue.main.async {

}

回答by Putz1103

Asynchronous means out of line, synchronous means in line. You can perform synchronous tasks and block multiple threads at once.

异步意味着不合线,同步意味着合线。您可以执行同步任务并一次阻塞多个线程。

If you are in a background thread and want to update a whole bunch of the user interface you call out to the main thread in a dispatchqueue. If you call dispatch_syncthen the code you are currently in waits for the dispatchto complete, thereby blocking the background thread you are in and blocking the UI while it updates the main thread.

如果您在后台线程中并且想要更新一大堆用户界面,您可以调用dispatch队列中的主线程。如果您调用,dispatch_sync则您当前所在的代码将等待dispatch完成,从而在更新主线程时阻塞您所在的后台线程并阻塞 UI。

But if you called dispatch_asyncthe background thread would continue with the rest of the code listed and the main thread would run the requested dispatchblock.

但是如果你调用dispatch_async后台线程将继续列出其余的代码,主线程将运行请求的dispatch块。

The same can be said when in the main thread. if you call a dispatch_syncfrom the main thread into a global or custom queue it will block the main thread while it runs the code in a separate thread. I can't say I know of a case where that would be used, but it's surely possible.

在主线程中也可以这样说。如果您dispatch_sync从主线程调用 a到全局或自定义队列中,它将阻塞主线程,同时它在单独的线程中运行代码。我不能说我知道会使用它的情况,但这肯定是可能的。

Whenever you have calculation code, webservice code, fetching code, whatnot that does not affect the UI it is best to do it in a separate thread. For this kind of stuff I would do a dispatch_asyncinto a global thread. Then when that code is completed I would run a dispatch_asyncback into the main thread to tell it to update the UI with whatever I just calculated.

每当您有计算代码、Web 服务代码、获取代码等不影响 UI 的内容时,最好在单独的线程中进行。对于这种东西,我会做dispatch_async一个全局线程。然后,当该代码完成时,我将dispatch_async返回到主线程,告诉它使用我刚刚计算的任何内容更新 UI。

Synchronous means blocking, asynchronous means it will complete at a later time (maybe right now) without blocking what you are currently doing.

同步意味着阻塞,异步意味着它将在稍后(也许现在)完成而不会阻塞您当前正在做的事情。

回答by mjdth

This discussion pretty much answers it: Asynchronous vs Multithreading - Is there a difference?

这个讨论几乎回答了它: 异步与多线程 - 有区别吗?

In the general case, an asynchronous call does not necessarily create a new thread. That's one way to implement it, with a pre-existing thread pool or external process being other ways. It depends heavily on language, object model (if any), and run time environment.

Asynchronous just means the calling thread doesn't sit and wait for the response, nor does the asynchronous activity happen in the calling thread.

在一般情况下,异步调用不一定会创建新线程。这是实现它的一种方式,预先存在的线程池或外部进程是其他方式。它在很大程度上取决于语言、对象模型(如果有)和运行时环境。

异步只是意味着调用线程不会坐下来等待响应,异步活动也不会发生在调用线程中。

So basically, other activities can happen while waiting for something to load, but it may or may not be done on separate threads.

所以基本上,在等待加载某些东西时可能会发生其他活动,但它可能会或可能不会在单独的线程上完成。