ios - UITextView 滚动时 NSTimer 不触发

标签 ios objective-c

我有一个 UITextView,我用它打印出我从文件中读取的大量数据。我把它放在 NSTimer 上这样我每秒输入一行数据 100 次,将其打印到 textView,然后处理数据并使用 NSLog 输出一些内容.但是,每当我滚动 textView 时,我注意到没有任何内容通过 NSLog 输出到控制台。直到滚动完成。

滚动条会阻塞主线程还是什么?

-(void) initialize{
    ...
    timer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(hit:) userInfo:nil repeats:YES];
}

-(void)hit:(NSTimer*)time{
    double percentage = (double)lineIndex/(double)lines.count;
    //NSLog(@"%f", percentage);
    if (lineIndex < lines.count){
        [self recievedString:[lines objectAtIndex:lineIndex]];
        lineIndex += 1;
    }else{
        [time invalidate];
        timer = nil;
        [self.delegate finished];
    }
}

-(void)recievedString:(NSString *)line{
    NSArray *pieces = [line componentsSeparatedByString:@","];
    double accZ = [pieces[0] doubleValue];
    double accMag = [pieces[1] doubleValue];
    double gyroX = [pieces[2] doubleValue];
    double gyroZ = [pieces[3] doubleValue];
    [self crunchDatawithAccZ:accZ andAccMag:accMag andGyroX:gyroX andGyroZ:gyroZ];
}

-(void)crunchDatawithAccZ:(double)accZ andAccMag:(double)accMag andGyroX:(double)gyroX andGyroZ:(double)gyroZ {
    accMag = accMag*ACC_SENSITIVITY/(pow(2,DATA_WIDTH-1));
    accZ = accZ*ACC_SENSITIVITY/(pow(2,DATA_WIDTH-1));
    gyroX = gyroX*GYRO_SENSITIVITY/(pow(2,DATA_WIDTH-1));
    gyroZ = gyroZ*GYRO_SENSITIVITY/(pow(2,DATA_WIDTH-1));

    NSLog(@"%f, %f, %f, %f\n", accZ, accMag, gyroX, gyroZ);
    [self.delegate didReceiveData:[NSString stringWithFormat:@"%f, %f, %f, %f\n", accZ, accMag, gyroX, gyroZ]];

    [gyroX_array addObject:@(fabs(gyroX))];
...
}

委托(delegate)方法:

-(void)didReceiveData:(NSString *)line{
    self.console.text = [self.console.text stringByAppendingFormat:@"\n%@", line];
    [self.console setContentOffset:CGPointMake(0, self.console.contentSize.height) animated:YES];
}

最佳答案

如果你检查方法的文档

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

它说(我突出显示了运行循环模式):

Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode. After seconds seconds have elapsed, the timer fires, sending the message aSelector to target.

当 iOS 跟踪触摸事件时,主运行循环以 UITrackingRunLoopMode 运行。根据您的代码的计时器在 NSDefaultRunLoopMode 中注册(A.K.A 主运行循环不会退出繁忙,可能只是空闲或等待事件。)。所以在 UITrackingRunLoopMode 中,runloop 非常忙,以使 UIKit 响应尽可能平滑。

要解决这个问题,你需要在 NSRunLoopCommonModes 中注册你的定时器(这个值作为模式被所有运行循环模式监控)。

这是我认为对您有帮助的文档摘录:

timers are associated with specific modes of your run loop. If a timer is not in the mode currently being monitored by the run loop, it does not fire until you run the run loop in one of the timer’s supported modes.

检查这个doc如果您不熟悉 runloop。

关于ios - UITextView 滚动时 NSTimer 不触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30337949/

相关文章:

IOS 应用卡在 IOS 版本 10.2.1 的启动画面中,没有错误

ios - 启用/禁用 UIButton 取决于 UITextField 中文本的长度

objective-c - 事件指示器不在 subview 的中心(与父 View 的大小不同)

ios - iPhone 6 plus 真机 UIScreen mainScreen 大小奇怪

ios - AppDelegate中发生奇怪的泄漏

iphone - 小时分钟秒到秒ios

ios - 在不播放视频的情况下加载 MPMoviePlayer。只是预览

ios - 如何在另一个 Storyboard中获取 ECSlidingViewController 的实例?

iphone - 增加推送通知徽章 iPhone

objective-c - 如何链接到 C 代码块中的委托(delegate)