Как получить текущее имя очереди в swift 3


У нас есть такая функция в swift 2.2 для печати сообщения журнала с текущим запущенным потоком:

func MyLog(_ message: String) {
    if Thread.isMainThread {
        print("[MyLog]", message)
    } else {
        let queuename = String(UTF8String: dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL))! // Error: Cannot convert value of type '()' to expected argument type 'DispatchQueue?'
        print("[MyLog] [\(queuename)]", message)
    }
}

Этот код больше не компилируется в swift 3.0. Как теперь получить имя очереди?


Вопрос, заданный о том, как определить, где два потока являются одним потоком или нет: Проверьте правильность очереди отправки в Swift 3. Принятый ответ предлагает использовать setSpecific, чтобы связать "метку" с созданной очередью. Однако это не решает проблему. здесь, потому что мы хотим знать имя очереди. И очередь может быть не обязательно создана нами самими.

4   18   2016-09-18 04:10:50

4 ответа:

Как Брент Роял-Гордон упоминается в его сообщении о lists.swift.org это дыра в текущем дизайне, но вы можете использовать этот ужасный обходной путь.

  func currentQueueName() -> String? {
        let name = __dispatch_queue_get_label(nil)
        return String(cString: name, encoding: .utf8)
    }

Если вам не нравятся небезопасные указатели и c-строки, есть другое, безопасное решение:

if let currentQueueLabel = OperationQueue.current?.underlyingQueue?.label {
    print(currentQueueLabel)
    // Do something...
}

Я не знаю ни одного случая, когда currentQueueLabel будет nil.

Это лучше всего работает для меня:

/// The name/description of the current queue (Operation or Dispatch), if that can be found. Else, the name/description of the thread.
public func queueName() -> String {
    if let currentOperationQueue = OperationQueue.current {
        if let currentDispatchQueue = currentOperationQueue.underlyingQueue {
            return "dispatch queue: \(currentDispatchQueue.label.nonEmpty ?? currentDispatchQueue.description)"
        }
        else {
            return "operation queue: \(currentOperationQueue.name?.nonEmpty ?? currentOperationQueue.description)"
        }
    }
    else {
        let currentThread = Thread.current
        return "UNKNOWN QUEUE on thread: \(currentThread.name?.nonEmpty ?? currentThread.description)"
    }
}



public extension String {

    /// Returns this string if it is not empty, else `nil`.
    public var nonEmpty: String? {
        if self.isEmpty {
            return nil
        }
        else {
            return self
        }
    }
}

Этот метод будет работать как для очереди операций, так и для очереди отправки.

    func printCurrnetQueueName()
    {
        print("Perform Operation \(String(describing: OperationQueue.current?.name!))")
    }