有没有办法记录方法正在运行/调用的线程或队列?就像是:
- (void)foo
{
NSLog(@"Running on %@ queue, %@ thread", queue, thread);
}
有没有办法记录方法正在运行/调用的线程或队列?就像是:
- (void)foo
{
NSLog(@"Running on %@ queue, %@ thread", queue, thread);
}
您可以使用+[NSThread currentThread]
. 那可能有一个name
属性,但如果你没有设置一个,不要依赖它。
队列比较棘手,因为“队列”有不同的含义。队列可以是NSOperationQueue
,您可以从中获取它name
(+[NSOperationQueue currentQueue]
同样,假设您设置了它)。
然后是调度队列。您可以使用 获取当前队列dispatch_get_current_queue()
,但请注意,即使从与队列无关的代码调用此函数(!)也会成功。在这种情况下,它返回默认的后台队列队列被标记,所以你可以调用dispatch_queue_get_label()
,如果你创建了带有标签的队列,你会得到它。
所以基本上,是的,你可以获得队列或线程——条件是所有代码都有一个关联的调度队列,即使它不是被调度的代码。您通常还可以为这些线程和队列获取有意义的名称,这对于调试很方便:但命名它们是您的责任。
这是我目前正在使用的一些 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)
要获取线程,您可以使用
NSLog(@"Running on %@ thread", [NSThread currentThread]);
您可以像这样获取当前的调度队列:
dispatch_queue_t dispatch_get_current_queue(void);
但标题有以下警告:
建议仅用于调试和记录目的:
代码不得对返回的队列做出任何假设,除非它是全局队列之一或代码自己创建的队列。如果该队列不是 dispatch_get_current_queue() 返回的队列,则代码不能假定在队列上同步执行不会出现死锁。
所以YMMV。