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

时间:2013-05-20 10:48:04

标签: ios objective-c multithreading grand-central-dispatch nsoperationqueue

有没有办法记录运行/调用方法的线程或队列?类似的东西:

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

4 个答案:

答案 0 :(得分:10)

您可以使用+[NSThread currentThread]获取当前主题。 可以拥有name属性,但如果你没有设置,则不要依赖它。

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

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

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

答案 1 :(得分:4)

这是我目前正在使用的一些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)

答案 2 :(得分:1)

要获取该主题,您可以使用

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

答案 3 :(得分:1)

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

dispatch_queue_t dispatch_get_current_queue(void);

但标题有以下警告:

  

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

     

代码不能   对返回的队列做出任何假设,除非它是其中之一   全局队列或代码本身创建的队列。代码必须   不要假设同步执行到队列是安全的   如果该队列不是返回的队列,则死锁   dispatch_get_current_queue()。

所以YMMV。