6

有沒有辦法記錄方法運行/調用的線程或隊列?喜歡的東西:記錄哪個隊列/正在運行一個方法

- (void)foo 
{ 
    NSLog(@"Running on %@ queue, %@ thread", queue, thread); 
} 
+0

'[NSThread currentThread]',見[這裏](http://stackoverflow.com/a/1616737/1971013)。 –

+0

http://stackoverflow.com/a/5166740/1407017&http://stackoverflow.com/a/1542071/1407017 – Amar

+0

這可能有所幫助:http://stackoverflow.com/a/30019141/1138755 – cromandini

回答

9

你可以得到當前線程與+[NSThread currentThread]。那可能有一個name財產,但如果你沒有設置一個不依賴它。

隊列比較棘手,因爲「隊列」的含義不同。排隊可能NSOperationQueue,您可以從+[NSOperationQueue currentQueue](假設您已設置它)再次獲取它的name

然後有調度隊列。您可以使用dispatch_get_current_queue()獲得當前隊列,但需要注意的是,即使從不與隊列(!)關聯的代碼中調用該函數,該函數也會成功。在這種情況下,它返回默認的後臺隊列隊列被標記,所以你可以調用dispatch_queue_get_label(),如果你創建了帶有標籤的隊列,你會得到。

所以基本上,你可以得到隊列或線程 - 但條件是所有的代碼都有一個關聯的調度隊列,即使它不是被調度的代碼。您通常也可以爲這些線程和隊列獲取有意義的名稱,這對調試非常方便:但是您有責任爲其命名。

+0

偉大的信息,謝謝格雷厄姆。 –

1

要獲得線程,你可以使用

NSLog(@"Running on %@ thread", [NSThread currentThread]); 
1

您可以獲得當前調度隊列是這樣的:

dispatch_queue_t dispatch_get_current_queue(void); 

但頭部有如下警告:

只推薦在調試和日誌記錄:

代碼必須而不是 對返回的隊列做出任何假設,除非它是全局隊列中的一個或者代碼自己創建的隊列。如果該隊列不是由 dispatch_get_current_queue()返回的那個,則代碼必須 不會假定從隊列的同步執行是從 死鎖安全的。

so YMMV。

2

這是我目前使用的一些Swift代碼。這部分是基於我以前在這裏張貼在堆棧溢出另一個答案:https://stackoverflow.com/a/41294559/253938

/// Struct to contain either the thread name or an (arbitrary) thread number for the current thread. 
/// This is partly inspired by code in BaseDestination.swift in XCGLogger. Main thread is 
/// arbitrarily given thread number 0. If no thread name can be determined then the memory address 
/// of the current Thread object is arbitrarily used as the thread number. 
/// 
/// Re use of "__dispatch_queue_get_label(nil)" (seen in XCGLogger) see here: 
/// https://stackoverflow.com/questions/40186868/get-gcd-label-in-swift-3 
internal struct ThreadInfo : CustomStringConvertible { 

    var threadName : String? = nil 
    var threadNumber : Int64? = nil 


    /// Initializer. 
    public init() { 
     // Process main thread (call it thread 0) and threads whose name can be determined 
     if Thread.isMainThread { 
     threadNumber = 0 
     } 
     else if let threadName = Thread.current.name, !threadName.isEmpty { 
     self.threadName = threadName 
     } 
     else if let queueName = String(validatingUTF8: __dispatch_queue_get_label(nil)), 
     !queueName.isEmpty { 
     threadName = queueName 
     } 
     else { 
     // Convert the memory address of the current Thread object into an Int64 and use it as the 
     // (arbitrary) thread number 
     let objPtr = Unmanaged.passUnretained(Thread.current).toOpaque() 
     let onePtr = UnsafeMutableRawPointer(bitPattern: 1)! // Absolute memory location 1 
     let rawAddress : Int64 = onePtr.distance(to: objPtr) + 1 // May include high-order bits 
     threadNumber = rawAddress % (256 * 1024 * 1024 * 1024) // Remove possible high-order bits 
     } 
    } 


    /// Method to implement CustomStringConvertible, returning either the thread name if possible or 
    /// else the (arbitrary) thread number. 
    public var description: String { 
     get { 
     return 
      threadName != nil ? String(describing: threadName!) : String(describing: threadNumber!) 
     } 
    } 
} 

要使用這只是實例化一個ThreadInfo有問題的線程上運行時。然後,您可以顯示ThreadInfo或將其嵌入到日誌記錄數據中。

let threadInfo = ThreadInfo() 
    print(threadInfo) 
相關問題