я могу позвонить в основной поток semaphore.wait ()? - PullRequest
0 голосов
/ 11 июня 2018

У меня есть метод, который дает мне статус аутентификации фотографии.

func photosAuthorizationStatus() -> PHAuthorizationStatus {
        var authStatus = PHAuthorizationStatus.notDetermined
        let semaphore = DispatchSemaphore(value: 0)
        PHPhotoLibrary.requestAuthorization { (status: PHAuthorizationStatus) in
            authStatus = status
            semaphore.signal()
        }
        semaphore.wait()
        return authStatus
    }

Я вызываю этот метод в viewDidAppear ViewController, но приложение не зависает.

Но если я вызываюsemaphore.wait, когда я спрашиваю mainQueue явно Приложение зависает.

DispatchQueue.main.async{
let semaphore = DispatchSemaphore(value: 0)
semaphore.wait()

}

// Выше кода заморозит приложение.

Могу ли я узнать причину?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

В заголовке вы спрашиваете:

можно ли вызвать основной поток semaphore.wait ()?

Вам следует избегать блокирования основного потока по любой причине,wait для семафоров или групп рассылки, или даже синхронная диспетчеризация (например, sync) чего-либо более чем несколько миллисекунд.Вы рискуете, если процесс сторожевого таймера убьет ваше приложение, если вы сделаете это в неподходящее время, и это приведет к ужасному UX.


Затем вы спросите:

DispatchQueue.main.async {
   let semaphore = DispatchSemaphore(value: 0)
   semaphore.wait()
}

Приведенный выше код заморозит приложение.

Могу ли я узнать причину

Этот код говорит: «заблокируйте основной поток, ожидающий signal на этом семафоре».Таким образом, до тех пор, пока не наступит signal, основной поток будет заблокирован.Но главный поток никогда не должен блокироваться, потому что он обслуживает, помимо прочего, пользовательский интерфейс, и ваше приложение будет зависать, если вы заблокируете основной поток.

В итоге, никогда не блокируйте основной поток.

0 голосов
/ 11 июня 2018

Создать завершение завершения в методе, который будет вызываться после успешного завершения авторизации запроса.См. Следующий код.

Убедитесь, что вы добавили ключ доступа "Privacy - Photo Library Usage Description" в файле Info.plist.

func photosAuthorizationStatus(completion: @escaping (PHAuthorizationStatus) -> Void) {
    PHPhotoLibrary.requestAuthorization { (status: PHAuthorizationStatus) in
        completion(status)
    }
}

Использование:

self.photosAuthorizationStatus { (status) in
    // use your status here
}

Выход:

enter image description here

...