You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C中NSThread调用触发NSInvalidArgumentException问题排查

问题分析与解决方案

首先咱们来拆解你遇到的NSInvalidArgumentException错误——这个报错的核心原因有两个,咱们一个个说:

1. NSThread初始化的参数完全用错了

你在callInBackground:selector:方法里写了这段代码:

NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(selector) object:nil];

这里犯了两个致命错误:

  • 线程的target你传成了self(也就是QAFeatTestCaseBase的实例),但实际上要执行的Bug8772方法是在子类Bug8772里定义的,所以应该用传入的target参数;
  • @selector(selector)是硬编码的错误写法——你需要用方法参数里的selector,而不是把selector当成方法名,这就是错误提示里说“target does not implement selector”的直接原因,因为QAFeatTestCaseBase根本没有叫selector的方法。

2. 方法命名不符合Objective-C规范(非报错原因,但建议修正)

你的业务方法Bug8772应该遵循Objective-C的命名惯例,用小写字母开头,比如改成bug8772,这样代码可读性更高,也符合行业习惯。


修正后的callInBackground:selector:方法

- (void)callInBackground:(id)target selector:(SEL)selector {
    // 这里改用传入的target和selector参数,而不是self和硬编码的@selector(selector)
    NSThread* thread = [[NSThread alloc] initWithTarget:target selector:selector object:nil];
    [thread setStackSize: 2*1024*1024];
    [thread start];
    while([thread isFinished] == NO) {
        usleep(1000);
    }
    [thread release];
}

测试类的调用部分如果改了方法名,记得同步更新selector:

@interface Bug8772 : QAFeatTestCaseBase
@end

@implementation Bug8772
- (void) testBug8772 {
    [self callInBackground:self selector:@selector(bug8772)];
}
- (void)bug8772 {
    // do stuff..
}
@end

更优的实现方式(避免低效的忙等)

你现在用while循环+usleep的方式等待线程完成,属于忙等,会白白浪费CPU资源。在Objective-C里有更优雅的替代方案:

方式1:用GCD(苹果推荐的并发方式)

GCD会自动管理线程池,代码简洁且高效,还不用手动处理线程生命周期:

- (void)callInBackground:(id)target selector:(SEL)selector {
    // dispatch_sync会自动等待后台任务执行完成
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [target performSelector:selector];
    });
}

方式2:用NSThread的原生等待方法

如果你坚持要用NSThread,可以用waitUntilDone:替代手动循环,它会让当前线程休眠直到目标线程完成,比忙等高效得多:

- (void)callInBackground:(id)target selector:(SEL)selector {
    NSThread* thread = [[NSThread alloc] initWithTarget:target selector:selector object:nil];
    [thread setStackSize: 2*1024*1024];
    [thread start];
    // 直接等待线程完成,无需手动循环
    [thread waitUntilDone:YES];
    [thread release];
}

内容的提问来源于stack exchange,提问作者Gerald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:09:33