记录正在运行方法的队列/线程

nev*_*ing 7 multithreading objective-c nsoperationqueue grand-central-dispatch ios

有没有办法记录运行/调用方法的线程或队列?就像是:

- (void)foo
{
    NSLog(@"Running on %@ queue, %@ thread", queue, thread);
}
Run Code Online (Sandbox Code Playgroud)

小智 10

你可以获得当前的线程+[NSThread currentThread].这可能有一个name属性,但如果你没有设置一个不依赖它.

队列比较棘手,因为"队列"有不同的含义.队列可以是一个NSOperationQueue,也可以抓住它name+[NSOperationQueue currentQueue](再次,假设你设置).

然后是派遣队列.您可以获取当前队列dispatch_get_current_queue(),但要注意,即使从与队列无关的代码调用此函数,该函数也会成功(!).在这种情况下,它返回默认的后台队列队列标记,因此您可以调用dispatch_queue_get_label(),如果您使用标签创建了队列,您将获得该标记.

所以基本上,是的,你可以获得队列或线程 - 条件是所有代码都有一个关联的调度队列,即使它不是调度的代码.您通常也可以为这些线程和队列获取有意义的名称,这对于调试很方便:但是您有责任为它们命名.


Ren*_*Pet 6

这是我目前正在使用的一些 Swift 代码。这部分基于我之前在 Stack Overflow 上发布的另一个答案: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:
/// /sf/ask/2813080791/
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!)
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需在有问题的线程上运行时实例化 ThreadInfo。然后您可以显示 ThreadInfo 或将其嵌入日志数据中。

  let threadInfo = ThreadInfo()
  print(threadInfo)
Run Code Online (Sandbox Code Playgroud)