Naming Threads in an NSOperationQueue
Asked Answered
P

4

8

NSOperationQueue creates many threads, as you'd expect, and desire. But when you pause the app and debug it in Xcode, it's unclear which threads belong to one operation queue and which belong to another.

I've tried:

[NSThread currentThread] setName: @"My amazing operation thread"]

but as threads are reused, this just means that many threads get this name and then never lose it. I've tried setting the thread name in -start and unsetting it in -finish, but the thread names never show up in the Xcode debugging thread list.

What's a good way of naming threads/operations to make them easier to debug in Xcode?

Picoline answered 21/3, 2013 at 23:14 Comment(1)
Naming threads is meaningless when working with queues. A queue may use any thread, technically, and which thread is an implementation detail. Multiple queues may share threads, again the details are left to the opaque implementation.Tacitus
M
4

To name your NSOperationQueue, you can use:

- (void)setName:(NSString *)newName

When debugging, the name of the thread appears un light gray under the thread.

Example: (thread 3 is mine)

enter image description here

From Apple's documentation:

Discussion

Names provide a way for you to identify your operation queues at run time. Tools may also use this name to provide additional context during debugging or analysis of your code.

Xcode is one of the "tools" that uses this information to provide additional context during debugging.

Misinform answered 21/3, 2013 at 23:16 Comment(8)
I have tried this and found it not to be the case. [_operationQueue setName: @"my awesome operation queue"]; Nothing shows up in the debug threadlist.Picoline
@NickLocking Well, I don't understand. I use it all the time… When debugging, the name of the thread appears in light gray under the thread, on the left pane in Xcode. See my example.Misinform
You can recognize the custom-named thread at the misspelled dispatch and at the jssensors in the name. What version of Xcode are you using? I am on Version 4.6.1 (4H512).Misinform
Latest version. The only thing I can think of is that I'm using concurrent operations.Picoline
@NickLocking That's probably the explanation. I am using it serially. What does Xcode tell you when you select "View Process by queue" instead of "by threads" (top right of the left panel, when debugging)?Misinform
Nothing useful. Everything appears unmarked except system stuff and whatever uses GCD.Picoline
Some for me. I have NSThread inherited class and I am doing [self setName: @"ScreenSharingProcessorThread"]; but in debug session view it still not showing name of that thread.Domineer
Xcode 6 shows "NSOperationQueue 0xaddress", even with the queue's name set.Monro
G
3

(This answer is tested only with Xcode 10.1)

To answer the question in the body of the post (not the title), you need to set the name of the OperationQueue's underlying queue. By doing so, that queue name will show in Xcode while debugging (just like the main or global DispatchQueues).

For example:

var queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
queue.qualityOfService = .background
queue.underlyingQueue = DispatchQueue(
    label: "my-queue-dispatch-queue", qos: .background)

This example will yield the following in Xcode 10.1: Example Xcode 10.1 Debug View

Reference to the underlyingQueue property: https://developer.apple.com/documentation/foundation/operationqueue/1415344-underlyingqueue

Sidenote: From experience, the "queue.qualityOfService = .SOMETHING" is necessary. See: https://bugs.swift.org/browse/SR-9742

Ganglion answered 24/1, 2019 at 7:31 Comment(0)
D
1

Fixed the problem by doing this:

[[NSThread currentThread] setName:@"ScreenSharingProcessorThread"];

instead of:

[self setName: @"ScreenSharingProcessorThread"];

Hope this helps

Domineer answered 7/8, 2014 at 15:25 Comment(0)
T
0

I also found that naming the NSOperationQueue will not name the thread in Xcode during debugging.

Solution: Add an operation that sets the thread's name, and add it to the queue once after creating the queue.

NameThreadOperation.h

#import <Foundation/Foundation.h>

@interface NameThreadOperation : NSOperation

@end

NameThreadOperation.m

#import "NameThreadOperation.h"

@implementation NameThreadOperation

- (void)main
{
    @autoreleasepool
    {
        [[NSThread currentThread] setName:@"Name of the thread"];
    }
}

@end

In your ViewController.m or whatever:

operationQueue = [[NSOperationQueue alloc] init];

#if defined(DEBUG)
    [self.operationQueue addOperation:[[NameThreadOperation alloc] init]];
#endif
Tania answered 14/11, 2014 at 14:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.