Objective-C中的同步和asynchronous调用与multithreading之间有什么区别?
最长的时间,我认为asynchronous是在后台线程上运行的东西的同义词,同步意味着在主线程(阻止UI更新和交互)。 我知道不在昂贵的动作的主线程上运行是因为它不允许UI动作发生,因为主线程被占用,但为什么同步麻烦?
但是,由于引起了我的注意,您可以在主线程上进行asynchronous调用,并在后台线程上进行同步调用。
我总是听到人们说不要同步或在主线程上使用昂贵的调用,因为它会阻止用户的用户界面。 这两个单独的问题,我应该确保我不这样做? 有什么区别?
当你同步调用某个东西时,意味着启动该操作的线程将在继续之前等待任务完成。 asynchronous意味着它不会等待。
话虽如此,当人们build议您asynchronous执行一些缓慢或昂贵的过程时,它们暗示不仅应该asynchronous运行它,而且应该在后台线程上执行该过程。 目标是释放主线程,以便它可以继续响应用户界面(而不是冻结),因此您正在asynchronous地将任务分派到后台线程。
所以,这有两个部分。 首先,使用GCD作为例子,你抓取一个背景队列(或者抓住一个全局背景队列,或者创build你自己的队列):
// 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);
其次,你asynchronous地将你的任务发送到该队列:
dispatch_async(queue, ^{ // the slow stuff to be done in the background });
操作队列的模式非常相似。 创build一个操作队列并将操作添加到该队列。
实际上,同步与asynchronous的区别与主队列与后台队列的区别是完全不同的。 但是当人们谈论“asynchronous运行一些缓慢的进程”时,他们真的说“在后台队列上asynchronous执行一些缓慢的进程”。
“同步”本质上是指“按顺序”。 基本上,当你做一个同步操作时,以后的所有事情都必须等待操作完成才能启动。
相反, “asynchronous”或多或less意味着“不按顺序”。 当您asynchronous执行某些操作时,可以立即运行以下代码,并在某个时间运行asynchronous操作。 它可能与其他线程上的其他代码并行运行。 它可能只是安排在相同的线程上的其他时间。
同步的概念本身与特定的线程没有任何关系。 这是关于你是否必须等待手术完成。
主要的线程在Cocoa(Touch)程序中有很大的意义。 AppKit在主线程上运行主事件循环,因此如果主线程正在等待某个操作完成,它将无法处理任何input或更新UI。 如果你有一段代码在后台线程上运行,运行同步代码将不会阻塞主事件循环 ,因为它不是等待同步操作完成的主线程。
同样,从放置在主线程上的后台线程执行长时间运行的asynchronous操作可能会导致问题,因为在后台线程不会等待操作完成的情况下,它仍然占用主线程上的时间事件循环需要运行的地方。
让我们举一些简单的例子:
asynchronous调用multithreading:
//方法在不同的线程中被调用,并且不会阻塞当前的线程。 [NSURLConnection sendAsynchronousRequest:request 队列:队列 completionHandler: ^(NSURLResponse *响应,NSData *数据,NSError *错误){ }];
multithreading同步调用:
//做一点事 dispatch_sync(queue,^ { //做别的事 }); //做更多的东西
在这里,你得到/ /做一些事情/ /做别的事情和/ /做更多的东西连续完成,即使//做别的事情是在不同的线程完成。
通常情况下,当人们使用不同的线程时,整个目的就是让一些东西不用等待就可以执行。 假设你想要下载大量的数据,但你想保持UI平滑。
因此,dispatch_sync很less使用。 但它在那里。 我个人从来没有使用过。 为什么不要求使用dispatch_sync的示例代码或项目。
asynchronous调用一个线程:
[self performSelector:@selector(doSomething)withObject:nil afterDelay:0];
在这里调用当前的runloop来完成'doSomething'。 换句话说,当前调用堆栈可以在调用“doSomething”之前完成(当前方法返回)。
同一个线程同步调用:
[self doSomething];
我不认为你需要解释这一点。
通常,asynchronous活动与线程不同,但是在iOS中,它们是使用这种方式实现的。 对所有语言来说都不是这样。 我们通常使用运行循环pipe理不同的asynchronous任务。
这个讨论相当多的答案: asynchronous与multithreading – 有没有区别?
在一般情况下,asynchronous调用不一定会创build一个新的线程。 这是实现它的一种方式,预先存在的线程池或外部进程是其他方式。 这在很大程度上取决于语言,对象模型(如果有的话)和运行时环境。
asynchronous只是意味着调用线程并不坐等待响应,asynchronous活动也不会在调用线程中发生。
所以基本上,其他活动可以在等待加载的时候发生,但是可能在单独的线程上完成,也可能不完成。
asynchronous是指脱机,同步意味着在线。 您可以执行同步任务并一次阻塞多个线程。
如果你在一个后台线程中,想更新一大堆用户界面,你可以调用一个dispatch
队列中的主线程。 如果调用dispatch_sync
那么当前的代码将等待dispatch
完成,从而阻塞您所在的后台线程,并在更新主线程时阻塞UI。
但是,如果您调用dispatch_async
,后台线程会继续执行剩余的代码,主线程将运行请求的dispatch
块。
在主线程中可以这样说。 如果您从主线程调用dispatch_sync
到全局或自定义队列中,它将阻止主线程在单独的线程中运行代码。 我不能说我知道一个会被使用的情况,但是这肯定是可能的。
每当你有计算代码,Web服务代码,获取代码,不会影响UI,最好是在一个单独的线程。 对于这种东西,我会做一个dispatch_async
到全局线程。 然后,当代码完成时,我会运行一个dispatch_async
回主线程告诉它用我刚刚计算的更新UI。
同步意味着阻塞,asynchronous意味着它会在稍后(也许现在)完成,而不会阻塞你正在做的事情。