8

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

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

4 回答 4

11

您可以使用+[NSThread currentThread]. 那可能有一个name属性,但如果你没有设置一个,不要依赖它。

队列比较棘手,因为“队列”有不同的含义。队列可以NSOperationQueue,您可以从中获取它name+[NSOperationQueue currentQueue]同样,假设您设置了它)。

然后是调度队列。您可以使用 获取当前队列dispatch_get_current_queue(),但请注意,即使从与队列无关的代码调用此函数(!)也会成功。在这种情况下,它返回默认的后台队列队列被标记,所以你可以调用dispatch_queue_get_label(),如果你创建了带有标签的队列,你会得到它。

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

于 2013-05-20T10:55:26.933 回答
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:
/// 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)
于 2017-03-07T10:15:51.287 回答
1

要获取线程,您可以使用

NSLog(@"Running on %@ thread", [NSThread currentThread]);
于 2013-05-20T10:53:57.000 回答
1

您可以像这样获取当前的调度队列:

dispatch_queue_t dispatch_get_current_queue(void);

但标题有以下警告:

建议仅用于调试和记录目的:

代码不得对返回的队列做出任何假设,除非它是全局队列之一或代码自己创建的队列。如果该队列不是 dispatch_get_current_queue() 返回的队列,则代码不能假定在队列上同步执行不会出现死锁。

所以YMMV。

于 2013-05-20T10:56:33.550 回答