в чем разница между синхронными и асинхронными вызовами в objective-c и многопоточностью?

<p>долгое время я думал, что асинхронный - это синоним выполнения чего-либо в фоновом потоке, а синхронный - в основном потоке (блокирование обновлений пользовательского интерфейса и взаимодействий). я понимаю, что не выполнение в основном потоке дорогостоящих действий объясняется тем, что оно не позволяет выполнять действия пользовательского интерфейса, поскольку основной поток занят, но почему синхронная работа является проблематичной?</p><p>однако с тех пор как я обратил внимание, вы можете выполнять асинхронные вызовы в основном потоке и синхронные вызовы в фоновых потоках.</p><p>я всегда слышу, как люди говорят, что не следует использовать дорогостоящие вызовы синхронно или в основном потоке, поскольку это заблокирует пользовательский интерфейс. эти две отдельные проблемы, которые я должен убедиться, я не делаю? какие есть отличия?</p>

<p>когда вы вызываете что-то синхронно, это означает, что поток, инициировавший эту операцию, будет ожидать завершения задачи, прежде чем продолжить. асинхронный означает, что он не будет ждать.</p><p>сказав это, когда люди предполагают, что вы выполняете какой-то медленный или дорогостоящий процесс асинхронно, они неявно предлагают не только выполнять асинхронно, но и делать это в фоновом потоке. цель состоит в том, чтобы освободить основной поток, чтобы он мог продолжать отвечать на пользовательский интерфейс (а не зависать), чтобы асинхронно отправлять задачи в фоновый поток.</p><p>итак, есть две части этого. во-первых, используя gcd в качестве примера, вы получаете фоновую очередь (либо одну из глобальных фоновых очередей, либо создаете свою):</p><pre><code>// 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); </code></pre><p>во-вторых, вы отправляете свои задачи в эту очередь асинхронно:</p><pre><code>dispatch\_async(queue, ^{ // the slow stuff to be done in the background }); </code></pre><p>шаблон для очередей операций очень похож. создайте очередь операций и добавьте операции в эту очередь.</p><p>в действительности, синхронное и асинхронное различие полностью отличается от основной очереди по сравнению с фоновой разницей. но когда люди говорят о "асинхронном запуске некоторого медленного процесса", они на самом деле говорят "асинхронно запускать некоторый медленный процесс в фоновой очереди".</p>

<p><strong>"синхронный"</strong> по сути означает <strong>"по порядку."</strong> по сути, когда вы выполняете синхронную операцию, все, что происходит позже, должно ждать завершения операции, прежде чем они начнутся.</p><p>и наоборот, <strong>"асинхронный"</strong> более или менее означает <strong>"не по порядку".</strong> когда вы делаете что-то асинхронно, следующий код может быть сразу запущен, и асинхронная операция будет выполнена… когда-нибудь , он может выполняться параллельно с остальным кодом в другом потоке. это может быть просто запланировано на какое-то другое время в том же потоке.</p><p>понятие синхронности само по себе не имеет ничего общего с конкретными потоками. речь идет о том, нужно ли вам ждать завершения операции или нет.</p><p>основное внимание в этом уделяется программам cocoa (touch). appkit запускает основной цикл обработки событий в главном потоке, поэтому, если основной поток ожидает завершения операции, он не может обработать ввод или обновить пользовательский интерфейс. однако если у вас есть фрагмент кода, работающий в фоновом потоке, синхронный код <em> не будет блокировать основной цикл событий </em>, потому что это не основной поток, ожидающий завершения синхронной операции.</p><p>точно так же длительная асинхронная операция из фонового потока, которую вы помещаете в основной поток <em>, может </em> вызвать проблемы, потому что пока фоновый поток не собирается чтобы дождаться завершения операции, она все еще занимает время в главном потоке, где должен выполняться цикл обработки событий.</p>

<p>позвольте нам привести несколько простых примеров:</p><p><strong>асинхронный вызов с многопоточностью:</strong></p><pre> // методы вызываются в другом потоке и не блокируют текущий поток. [.\_\_ }];. </pre><p><strong>синхронный вызов с многопоточностью:</strong></p><pre> // делаем что-то dispatch\_sync (queue, ^ { // делаем что-то еще }); // делаем больше материала </pre><p>здесь вы получаете // делать что-то // делать что-то еще и // делать больше вещей, которые выполняются последовательно, даже если // делать что-то еще делается в другом потоке.</p><p>обычно, когда люди используют разные потоки, цель состоит в том, чтобы что-то могло быть выполнено без ожидания. скажем, вы хотите загрузить большой объем данных, но хотите, чтобы интерфейс был гладким.</p><p>следовательно, dispatch\_sync используется редко. но это там. я лично никогда не использовал это. почему бы не попросить пример кода или проекта, который использует dispatch\_sync.</p><p><strong>асинхронный вызов с одним потоком:</strong></p><pre> [self executeselector: @selector (dosomething) withobject: nil afterdelay: 0]; </pre><p>здесь текущий цикл выполнения для завершения до вызова dosomething. другими словами, текущий стек вызовов может быть завершен (текущий метод возвращается) до вызова dosomething.</p><p><strong>синхронный вызов с одним потоком:</strong></p><pre> [self dosomething]; </pre><p>я не думаю, что вам нужно объяснение этого.</p><p>в общем случае асинхронная активность не совпадает с многопоточностью, однако в ios они реализованы таким образом. это не верно для всех языков. обычно мы управляем различными асинхронными задачами, используя циклы выполнения.</p>

<p><strong>swift 3, 4, 4,2</strong> <strong><em> synchronous </em></strong> означает, что поток, инициировавший эту операцию, будет ожидать для завершения задачи, прежде чем продолжить.</p><pre><code>dispatchqueue.main.sync { } </code></pre><p><strong><em> асинхронный </em></strong> означает, что выполнение задачи выполняется в фоновом режиме и может уведомить вас о завершении, что означает, что он не будет ждать.</p><pre><code>dispatchqueue.main.async { } </code></pre>

<p>асинхронные средства вне строки, синхронные средства в строке. вы можете выполнять синхронные задачи и блокировать несколько потоков одновременно.</p><p>если вы находитесь в фоновом потоке и хотите обновить весь набор пользовательских интерфейсов, вы вызываете основной поток в очереди <code>dispatch</code>. если вы вызываете <code>dispatch\_sync</code>, то код, в котором вы сейчас находитесь, ждет завершения <code>dispatch</code>, блокируя тем самым фоновый поток, в котором вы находитесь, и блокируя пользовательский интерфейс, пока он обновляет основной поток.</p><p>но если бы вы вызвали <code>dispatch\_async</code>, фоновый поток продолжил бы с остальной частью кода в списке, и основной поток запустил бы запрошенный блок <code>dispatch</code>.</p><p>то же самое можно сказать, когда в основной теме. если вы вызываете <code>dispatch\_sync</code> из основного потока в глобальную или пользовательскую очередь, он блокирует основной поток, пока он запускает код в отдельном потоке. я не могу сказать, что знаю случай, когда это будет использовано, но это, безусловно, возможно.</p><p>всякий раз, когда у вас есть код расчета, код веб-службы, выборка кода и все такое, что не влияет на пользовательский интерфейс, лучше всего делать это в отдельном потоке. для такого рода вещей я бы сделал <code>dispatch\_async</code> в глобальном потоке. затем, когда этот код будет завершен, я запускаю <code>dispatch\_async</code> обратно в основной поток, чтобы сообщить ему об обновлении пользовательского интерфейса в соответствии с тем, что я только что рассчитал.</p><p>синхронный означает блокирование, асинхронный означает, что он завершится в более позднее время (возможно, прямо сейчас), не блокируя то, что вы делаете в данный момент.</p>

<p>это обсуждение в значительной степени отвечает на это: <a href="https://stackoverflow.com/questions/600795/asynchronous-vs-multithreading-is-there-a-difference">асинхронный против многопоточности - есть ли разница?</a> </p><blockquote> <p>в общем случае асинхронный вызов не обязательно создает новый поток. это один из способов его реализации, с другими способами уже существующий пул потоков или внешний процесс. это сильно зависит от языка, объектной модели (если есть) и среды выполнения.</p> <p>асинхронный означает, что вызывающий поток не сидит и не ожидает ответа, а также не происходит асинхронного действия в вызывающем потоке.</p> </blockquote><p>поэтому в основном другие действия могут происходить в ожидании загрузки чего-либо, но это может выполняться или не выполняться в отдельных потоках.</p>