我想使用C函数启动一个新线程,而不是使用Objective-C方法.我试过了
[NSThread detachNewThreadSelector: @selector(func) toTarget: nil withObject: id(data)];
我在哪里
void func(void *data) { // ... }
和data是一个void *,但我在objc_msgSend中遇到运行时崩溃,调用来自
-[NSThread initWithTarget:selector:object:]
我该怎么做?它甚至可能吗?
解决方法
滚动你自己:
// In some .h file. #import to make the extension methods 'visible' to your code. @interface NSThread (FunctionExtension) +(void)detachNewThreadByCallingFunction:(void (*)(void *))function data:(void *)data; -(id)initWithFunction:(void (*)(void *))function data:(void *)data; @end // In some .m file. @implementation NSThread (FunctionExtension) +(void)startBackgroundThreadUsingFunction:(id)object { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; void (*startThreadFunction)(void *) = (void (*)(void *))[[object objectForKey:@"function"] pointerValue]; void *startThreadData = (void *) [[object objectForKey:@"data"] pointerValue]; if(startThreadFunction != NULL) { startThreadFunction(startThreadData); } [pool release]; pool = NULL; } +(void)detachNewThreadByCallingFunction:(void (*)(void *))function data:(void *)data { [[[[NSThread alloc] initWithFunction:function data:data] autorelease] start]; } -(id)initWithFunction:(void (*)(void *))function data:(void *)data { return([self initWithTarget:[NSThread class] selector:@selector(startBackgroundThreadUsingFunction:) object:[NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:function],@"function",[NSValue valueWithPointer:data],@"data",NULL]]); } @end
注意:我写了上面的代码,并将其放在公共领域. (有时律师喜欢这种东西)它也完全没有经过考验!
你可以随时删除NSAutoreleasePool位,如果你可以保证线程入口函数也创建一个…但它是无害的,没有任何速度惩罚,并使调用任意C函数更简单.我会说保持它在那里.
你可以像这样使用它:
void bgThreadFunction(void *data) { NSLog(@"bgThreadFunction STARTING!! Data: %p",data); } -(void)someMethod { // init and then start later... NSThread *bgThread = [[[NSThread alloc] initWithFunction:bgThreadFunction data:(void *)0xdeadbeef] autorelease]; // ... assume other code/stuff here. [bgThread start]; // Or,use the all in one convenience method. [NSThread detachNewThreadByCallingFunction:bgThreadFunction data:(void *)0xcafebabe]; }
运行时:
2009-08-30 22:21:12.529 test[64146:1303] bgThreadFunction STARTING!! Data: 0xdeadbeef 2009-08-30 22:21:12.529 test[64146:2903] bgThreadFunction STARTING!! Data: 0xcafebabe