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

macOS循环执行期间支持用户输入的Objective-C开发问题咨询

你提出的批量创建NSTimer方案的缺陷
  • 性能损耗过高:一次性创建10000个定时器实例并全部加入主运行循环,会产生大量不必要的内存占用和调度开销,总循环次数越大,性能损耗越明显。
  • 执行逻辑不可控:所有定时器的触发时间均设置为0.1秒后,会出现大量定时器扎堆触发的情况,短时间内占用大量主线程资源容易引发UI掉帧,整体任务的执行时长也无法精准控制。
  • 停止逻辑不彻底:设置stopBatch = true后,已经加入调度队列的所有定时器依然会依次触发,只是执行时直接返回,这些无效调度依然会占用系统资源,不会主动被移除。
  • 维护成本高:如果需要调整总执行次数、单步执行的步长,都需要同时修改定时器创建逻辑和timerCalled内部的业务逻辑,后续迭代容易出现不兼容问题。
低改造成本的可选解决方案

方案1:主循环手动处理运行循环事件(改造成本最低)

仅需在原主线程循环逻辑中新增一行代码,手动让主运行循环处理一次用户输入等事件,无需拆分UI逻辑,改动量极小:

-(void) runMain{
    stopBatch = false;
    [textData setStringValue:@"Start"];
    [textData displayIfNeeded];

    NSString * iString = @"0";
    for (int i=0;i<=10000 ;i++)
    {
        if(stopBatch) break;
        
        iString= [NSString stringWithFormat: @"%d",i];
        [textData setStringValue:iString];
        [textData displayIfNeeded];
        
        // 手动处理当前队列中的所有事件,处理完成立刻返回,无多余等待
        [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
    }
}

方案2:单个重复定时器方案

仅创建一个重复定时器替代批量创建定时器,性能开销更低,停止逻辑更彻底:

// 新增类属性
@property (nonatomic, assign) NSInteger iVal;
@property (nonatomic, strong) NSTimer *batchTimer;

-(void) runMain{
    stopBatch = false;
    self.iVal = 0;
    // 仅创建1个重复定时器,间隔可根据业务需求调整
    self.batchTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(timerCalled) userInfo:nil repeats:YES];
}

-(void)timerCalled{
   if(stopBatch || self.iVal >= 10000) {
       [self.batchTimer invalidate];
       self.batchTimer = nil;
       return;
   }
   // 单次执行10个步长,可根据需要调整
   for (int i=0;i<10;i++)
   {
       self.iVal++;
       NSString *iString = [NSString stringWithFormat: @"%ld",self.iVal];
       [textData setStringValue:iString];
   }
}

方案3:后台线程+主线程UI更新(性能最优)

仅需要将UI更新的代码包裹到主线程调度中,其余逻辑无需改动,即可充分利用多线程性能:

-(void)runBatchBackground{
    stopBatch = false;
    dispatch_queue_t backgroundQueue = dispatch_queue_create("BatchQueue",nil);
    dispatch_async(backgroundQueue, ^(void){
        for (NSInteger i=0;i<=10000 ;i++)
        {
            if(stopBatch) break;
            
            // 仅将UI更新操作抛到主线程执行
            dispatch_async(dispatch_get_main_queue(), ^{
                NSString *iString = [NSString stringWithFormat: @"%ld",i];
                self.textData.stringValue = iString;
            });
            
            // 循环执行过快时可加微小延时控制UI刷新频率,避免主线程负载过高
            // usleep(1000);
        }
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:39:03