Pull to refresh

Comments 14

Отличная статья, Спасибо.
Было бы неплохо написать вторую часть об RxSwift.

UFO just landed and posted this here
Спасибо за статью. Отлично все разобрано.
НИКОГДА НЕ вызывайте метод sync на main queue, потому что это приведет к взаимной блокировке (deadlock) вашего приложения!

Не совсем понял, про какой случай речь? Нельзя вообще вызывать конструкцию DispatchQueue.main.sync?
Если же речь идет о вызове DispatchQueue.main.sync в Main Thread, то это относится ко всем задачам, выполняемым в одной и той же очереди (Dispatch Queues and Thread Safety):
Do not call the dispatch_sync function from a task that is executing on the same queue that you pass to your function call. Doing so will deadlock the queue. If you need to dispatch to the current queue, do so asynchronously using the dispatch_async function.

То есть следующий код вызовет deadlock:
let queue = DispatchQueue(label: "com.tursunov.app.exampleQueue")

queue.async {
    // ...
    queue.sync { // deadlock
        // ...
    }
}


При этом следующий кусок кода имеет право на достойное выполнение. Или я ошибаюсь?

let queue = DispatchQueue(label: "com.tursunov.app.exampleQueue")

queue.async {
    // ...
    DispatchQueue.main.sync { // there's no deadlock
        // ...
    }
    // ...
}



За статью огромное спасибо, must have. Теперь жду про Operation :)
И да, deadlock еще может быть в таком случае:

let queue = DispatchQueue(label: "com.tursunov.app.exampleQueue")

queue.sync {
    
    print(Thread.isMainThread) // true
  
    DispatchQueue.main.sync { // deadlock
        // ...
    }
}


Ну и стоит учесть, что все примеры из главной очереди запускаются.
Вопрос такой, а как избежать такого момента: если я поставлю на загрузку в задаче класса .background несколько гигабайт картинок, и уберу приложение в бэкграунд, то в пределах минуты приложение из бэкграунда закроется со словами, мол, использует > 80% CPU. И загрузка не завершится.
Как задать потоку .background такое состояние, чтобы он потреблял определённое количество ресурсов процессоров (<80%)? А то ОС просто закроет его. В foreground такой проблемы нету
Супер, огонь!
Статья большая, поэтому неудивительно, что встречаются опечатки. В основном некритичные, так что ничего страшного, всё-таки такая большая работа была проделана! Но, наверное, стоит исправить хотя бы одну, критичную, чтобы не вводить новичков в заблуждение. :]

А именно, в конце в разделе «10. Функция asyncAfter (deadline: .now() + 0.1, qos: .userInteractive) c изменением приоритета» нужно в выводе написать НЕ СОВПАДАЮТ. Очевидно, пропущена частица НЕ, что меняет смысл вывода на противоположный.

Ну, и вот здесь, на мой взгляд, стоит перефразировать одно предложение:
«Барьеры GCD делают одну интересную вещь — они ожидают момента, когда очередь будет полностью пуста, перед тем как выполнить свое замыкание.»

Всё же лучше написать как-то вот так, как считаете?

«Барьеры GCD делают одну интересную вещь: они заставляют очередь временно не начинать новые задачи и ждут, пока все работающие в очереди задачи закончат свою работу, а затем выполняют свое замыкание.»

А то, когда я только начинал знакомство с многопоточностью (месяца 4 назад) и впервые прочитал эту статью, мне эти фразы вынесли мозг :]]]

Спасибо за Ваш труд!
Все исправлено. Спасибо вам огромное за очень важные замечания.
UFO just landed and posted this here

Класс Operation имеет метод cancel(), однако использование этого метода только устанавливает свойство isCancelled в true, а что семантически означает «удаление» операции можно определить только при создании subclass Operation.  Например, в случае загрузки данных из сети можно определить cancel() как отключение операции от сетевого взаимодействия.

Посмотрите мою другую статью "Concurrency в Swift 3 и 4. Operation и OperationQueue" в Habr, специально посвященную Operation.

https://habr.com/ru/post/335756/

По-моему там есть пример.

Sign up to leave a comment.

Articles