我正在开发基于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而不是数量没有增加,只需等到滚动结束并反复增加。
任何人都可以告诉我可能的原因以及如何避免这个问题。
感谢。
答案 0 :(得分:0)
首先,您需要从后台线程启动计时器。将此代码更换为启动计时器:
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++
不需要在主队列上安排。上面的代码已经过您的代码测试,并且可以显示正常工作。
答案 1 :(得分:0)
我找到了上述问题和解决方案的来源。 主要问题是关于NSRunLoopMode。 如果您使用的是NSTimer或performSelector对象,则默认情况下会将RunLoopMode的模式分配给NSDefaulRunLoopModes,这会在您滚动页面时驱动Timers停止。 解决方案是将计时器和performSelectors添加到NSRunLoopCommonModes而不是使用NSDefaultRunLoopModes。
这是我找到的解决方案。
感谢您的支持