[Runloop]滑动ScrollView的同时流畅加载页面

runLoopMode:

  • NSDefaultRunLoopMode:默认的运行模式,用于大部分操作,除了NSConnection对象事件。
  • NSEventTrackingRunLoopMode:用于跟踪触摸事件触发的模式(例如UIScrollView上下滚动)。
  • NSRunLoopCommonModes:是一个模式集合,当绑定一个事件源到这个模式集合的时候就相当于绑定到了集合内的每一个模式。

例:

NSTimer* timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(readTimer) userInfo:nil repeats:YES];

通过以上方法注册NSTimer时,系统默认使用NSDefaultRunLoopMode模式,于是当界面在处理触摸事件时,runloop处于NSEventTrackingRunLoopMode,即不会处理计时器时间,所以导致Timer在界面滑动等事件产生时不会触发计时器。
所以应该用以下方法开启定时器,将runLoopMode设置为NSRunLoopCommonModes。

NSTimer* timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(readTimer) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

同理,在进行网络请求时,返回参数处理也默认使用NSDefaultRunLoopMode模式,通过以下方法即可解决该问题

NSURLConnection *connection = [[NSURLConnection alloc]
                           initWithRequest:request
                           delegate:self
                           startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
        forMode:NSRunLoopCommonModes];//修改mode
[connection start];

AFNetworking框架中对返回参数的处理默认使用NSRunLoopCommonModes,所以不用担心这个问题。


适用runloop的场合:

  1. 使用port或是自定义的input source来和其他线程进行通信
  2. 在线程(非主线程)中使用timer
  3. 使用 performSelector…系列(如performSelectorOnThread, …)
  4. 使用线程执行周期性工作

你可能感兴趣的:([Runloop]滑动ScrollView的同时流畅加载页面)