繁体   English   中英

问题:iOS UITableView滚动停止其他任务

[英]Issue: iOS UITableView scrolling stops other task

我正在开发基于TCPIP上的异步套接字通信运行的应用程序。 该应用程序的目的是周期性地(2秒)从服务器获取数据,并在tableview上列出数据。

到目前为止,我已经完成了编码和所有工作。 该应用程序运行正常。 但是,当我开始在UITableview中滚动时,循环获取将停止,直到tableviews声明滚动结束为止。

我没有添加所有代码,而是添加了具有相同行为的示例代码。 在这个示例项目中,我创建了计时器。 屏幕上有一个标签显示计数器和按钮来启动/停止计时器。 在屏幕上,我还添加了uitextview,它具有相当长的文本,只是启用了滚动。

这是代码

#import <UIKit/UIKit.h>
int i;

@interface ViewController : UIViewController{



}

@property (strong, nonatomic)  NSTimer *timer;

@property (strong, nonatomic) IBOutlet UILabel *label;
@property (strong, nonatomic) IBOutlet UIButton *txtBtn;
- (IBAction)btnStartStop:(id)sender;

@end


#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize label,txtBtn, timer;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    i = 0;
    //timer = [[NSTimer alloc] init];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)btnStartStop:(id)sender {
    if ([txtBtn.titleLabel.text isEqualToString:@"Start"]) {
        [txtBtn setTitle:@"Stop" forState:UIControlStateNormal];

        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timer_Running) userInfo:nil repeats:YES];
            NSLog(@"Timer Started");
    }
    else{
        [txtBtn setTitle:@"Start" forState:UIControlStateNormal];
        [timer invalidate];
        NSLog(@"Timer Stopped");
    }


}

-(void)timer_Running{
    NSLog(@"Timer Running");
    label.text = [NSString stringWithFormat:@"%i", i];
    i++;
}


@end

对于上面的代码; 当单击开始按钮时,计数器启动,并且在标签上您可以看到每增加1s。 但是,一旦您在UITextView上触摸并向上/向下滚动,计数就不会增加,只需等到滚动到结束并抵消相应的增量即可。

谁能告诉我可能的原因以及如何避免此问题。

谢谢。

首先,您需要从后台线程启动计时器。 替换您必须启动计时器的代码,方法是:

timer = [NSTimer timerWithTimeInterval:0.1
                                         target:self
                              selector:@selector(timer_Running:)
                                       userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

其次,由于您的计时器现在将在后台线程中触发,因此您需要从主线程访问UIKit:

-(void) timer_Running:(NSTimer *)timer {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"Timer Running");
        label.text = [NSString stringWithFormat:@"%i", i];
    });
    i++;
}

请注意,不需要在主队列上调度i++ 上面的代码已经与您的代码一起测试过,并且可以正常工作。

我发现了上述问题的根源和解决方案。 主要问题与NSRunLoopMode有关。 如果您使用的是NSTimer或performSelector对象,则默认情况下将RunLoopMode的模式分配给NSDefaulRunLoopModes,这会导致Timers在滚动页面时停止。 解决方案是将计时器和performSelector添加到NSRunLoopCommonModes中,而不是使用NSDefaultRunLoopModes。

这是我发现的解决方案。

谢谢你的支持

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM