C函数可以用作Cocoa中的选择器吗?

Jes*_*der 6 c multithreading objective-c selector

我想使用C函数启动一个新线程,而不是使用Objective-C方法.我试过了

[NSThread detachNewThreadSelector: @selector(func) toTarget: nil withObject: id(data)];
Run Code Online (Sandbox Code Playgroud)

我在哪里

void func(void *data) {
   // ...
}
Run Code Online (Sandbox Code Playgroud)

并且data是一个void *,但我得到了一个运行时崩溃objc_msgSend,调用来自

-[NSThread initWithTarget:selector:object:]
Run Code Online (Sandbox Code Playgroud)

我该怎么做?它甚至可能吗?

joh*_*hne 10

滚动你自己:

// 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
Run Code Online (Sandbox Code Playgroud)

注意:我写了上面的代码,并将其放在公共领域.(有时律师喜欢这种东西)它也完全没有经过考验!

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];
}
Run Code Online (Sandbox Code Playgroud)

运行时:

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
Run Code Online (Sandbox Code Playgroud)