Как указывает Олег, размещение readLine()
в конце кода верхнего уровня предотвратит завершение программы до тех пор, пока вы не нажмете Enter
в терминале или там, где указывает FileHandle.standardInput
. Это, вероятно, подходит для быстрого тестирования кода в отладчике или на игровой площадке. Бесконечный цикл также будет работать, хотя вам придется фактически завершить его в отладчике или с помощью kill
из командной строки.
Настоящая проблема в том, почему вы не хотите использовать семафор. Поскольку их нетрудно использовать, я рискну предположить, что это просто потому, что вы не хотите загрязнять свой обработчик завершения задачи асинхронных данных семафором, когда вам, вероятно, нужно только дождаться данных для тестирования. целей.
Если предположить, что моя догадка верна, то на самом деле проблема заключается не в использовании семафора, а в том, где, по вашему мнению, вам нужно их поместить. Как однажды сказал Дэвид Уиллер: «Любую проблему можно решить, добавив уровень косвенности.
Вы не хотите, чтобы семафор явно был в обработчике завершения, который вы передаете dataTask
. Таким образом, одним из решений было бы заставить gizlo
принимать собственный обработчик завершения, а затем создать метод, который вызывает gizlo
с замыканием, обрабатывающим семафор. Таким образом, вы можете разделить их и даже добавить гибкости для других целей. Я изменил ваш код для этого:
import Foundation
import Dispatch // <-- Added - using DispatchSemaphore
class test{
func gizlo(_ completion: ((Result<[String: Any]?, Error>) -> Void)? = nil) { // <-- Added externally provided completion handler
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: "https://itunes.apple.com/fr/rss/topmovies/limit=25/json")!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
let result: Result<[String: Any]?, Error>
if let responseError = error { // <-- Changed to optional binding
print(responseError.localizedDescription)
result = .failure(responseError) // <-- Added this
} else {
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
{
print(json)
result = .success(json) // <-- Added this
}
else { // <-- Added this else block
result = .success(nil)
}
} catch {
print("error in JSONSerialization")
result = .failure(error) // <-- Added this
}
}
completion?(result) // <-- Added this call
})
task.resume()
}
func blockingGizlo() throws -> [String: Any]? // <-- Added this method
{
let sem = DispatchSemaphore(value: 1)
sem.wait()
var result: Result<[String: Any]?, Error>? = nil
gizlo {
result = $0
sem.signal()
}
sem.wait() // This wait will block until the closure calls signal
sem.signal() // Release the second wait.
switch result
{
case .success(let json) : return json
case .failure(let error) : throw error
case .none: fatalError("Unreachable")
}
}
}
let tr=test()
do {
let json = try tr.blockingGizlo()
print("\(json?.description ?? "nil")")
}
catch { print("Error: \(error.localizedDescription)") }
person
Chip Jarred
schedule
26.02.2021