From ae8a9465306eaee5bb1478b74057e1bdf540b1db Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 30 Dec 2014 02:29:26 +0100 Subject: =?UTF-8?q?+[NSThread=20detachNewThreadWithName:=E2=80=A6]=20chang?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The method never did the one extra thing it should do, because… see comment in the code. Let's see how this works out :) --- Source/SPThreadAdditions.m | 60 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/Source/SPThreadAdditions.m b/Source/SPThreadAdditions.m index c1f0a52b..74476888 100644 --- a/Source/SPThreadAdditions.m +++ b/Source/SPThreadAdditions.m @@ -29,17 +29,69 @@ // More info at #import "SPThreadAdditions.h" +#import + +//this is a "private" class only needed by the +detachNewThreadWithName:… method below. +@interface SPNamedThread : NSObject { + @private + NSString *name; + id object; + SEL selector; +} +- (id)initWithTarget:(id)aObject selector:(SEL)aSelector name:(NSString *)aName; +- (void)run:(id)argument; +@end @implementation NSThread (SPThreadAdditions) + (void)detachNewThreadWithName:(NSString *)aName target:(id)aTarget selector:(SEL)aSelector object:(id)anArgument { - NSThread *newThread = [[NSThread alloc] initWithTarget:aTarget selector:aSelector object:anArgument]; - if (aName) { - [newThread setName:aName]; - } + // -[NSThread setName:] has two limitations when it comes to visibility in Xcode: + // a) Xcode only updates the thread name in UI once (on the first time the thread is shown in the debugger). + // b) Internally this method calls + // int pthread_setname_np(const char*); + // which, as can be seen, does not allow to specify a thread id. Therefore it is skipped if . + // Unfortunately this (and not the property of the NSThread) seems to be the actual name shown in Xcode. + // The consequence is, we can only set a thread's name from within the thread, so let's add a proxy object to do that. + SPNamedThread *namedThread = [[SPNamedThread alloc] initWithTarget:aTarget selector:aSelector name:aName]; + + NSThread *newThread = [[NSThread alloc] initWithTarget:namedThread selector:@selector(run:) object:anArgument]; [newThread start]; [newThread autorelease]; + [namedThread autorelease]; +} + +@end + +#pragma mark - + +@implementation SPNamedThread + +- (id)initWithTarget:(id)aObject selector:(SEL)aSelector name:(NSString *)aName +{ + if(self = [super init]) { + name = [aName copy]; + object = [aObject retain]; + selector = aSelector; + } + return self; +} + +- (void)run:(id)argument +{ + [[NSThread currentThread] setName:name]; + + void (*msgsend)(id, SEL, id) = (void (*)(id, SEL, id)) objc_msgSend; //hint for the compiler + + msgsend(object,selector,argument); +} + +- (void)dealloc +{ + [object release], object = nil; + selector = NULL; + [name release], name = nil; + [super dealloc]; } @end -- cgit v1.2.3