NSRunLoop

什么是runLoop

NSRunLoop是消息机制的处理模式
NSRunLoop的作用在于有事情做的时候使的当前NSRunLoop的线程工作,没有事情做让当前NSRunLoop的线程休眠
NSTimer默认添加到当前NSRunLoop中,也可以手动制定添加到自己新建的NSRunLoop
NSRunLoop就是一直在循环检测,从线程start到线程end,检测inputsource(如点击,双击等操作)同步事件,检测timesource同步事件,检测到输入源会执行处理函数,首先会产生通知,corefunction向线程添加runloop observers来监听事件,意在监听事件发生时来做处理。
在单线程的app中,不需要注意Run Loop,但不代表没有。程序启动时,系统已经在主线程中加入了Run Loop。它保证了我们的主线程在运行起来后,就处于一种“等待”的状态(而不像一些命令行程序一样运行一次就结束了),这个时候如果有接收到的事件(Timer的定时到了或是其他线程的消息),就会执行任务,否则就处于休眠状态。
runloopmode是一个集合,包括监听:事件源,定时器,以及需通知的runloop observers
模式包括:
default模式:几乎包括所有输入源(除NSConnection) NSDefaultRunLoopMode模式
mode模式:处理modal panels
connection模式:处理NSConnection事件,属于系统内部,用户基本不用
event tracking模式:如组件拖动输入源 UITrackingRunLoopModes 不处理定时事件
common modes模式:NSRunLoopCommonModes 这是一组可配置的通用模式。将input sources与该模式关联则同时也将input sources与该组中的其它模式进行了关联。
每次运行一个run loop,你指定(显式或隐式)run loop的运行模式。当相应的模式传递给run loop时,只有与该模式对应的input sources才被监控并允许run loop对事件进行处理(与此类似,也只有与该模式对应的observers才会被通知)

//广告业
例:
1).在timer与table同时执行情况,当拖动table时,runloop进入UITrackingRunLoopModes模式下,不会处理定时事件,此时timer不能处理,所以此时将timer加入到NSRunLoopCommonModes模式(addTimer forMode)
2).在scroll一个页面时来松开,此时connection不会收到消息,由于scroll时runloop为UITrackingRunLoopModes模式,不接收输入源,此时要修改connection的mode
[scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSRunLoopCommonModes];

A.Timer和scrollView一起使用的时候,如果一直滚动scrollView 此时 timer的事件将不会处理
解决方案:1.将timer添加到指定的RunLoopMode中
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

2.创建子线程 把timer放到子线程的RunLoop中

B.子线程实现异步下载

Demo

@implementation ViewController

  • (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIScrollView *table = [[UIScrollView alloc] initWithFrame:self.view.bounds];

    for (NSInteger i = 0; i < 3; i++) {
    UIView view = [[UIView alloc] initWithFrame:CGRectMake(i 375, 0, 375, 667)];

    view.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0f green:arc4random() % 256 / 255.0f blue:arc4random() % 256 / 255.0f alpha:1.0f];
    
    [table addSubview:view];
    

    }

    table.contentSize = CGSizeMake( 3 * 375, 667);

    [self.view addSubview:table];

    //将timer添加到指定的RunLoopMode中 NSRunLoopCommonModes
    //[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

    //2.把timer放到子线程
    [NSThread detachNewThreadSelector:@selector(createThread) toTarget:self withObject:nil];
    }

-(void)createThread
{
if 0
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timeChange) userInfo:nil repeats:YES];

//创建一个 runLoop对象  并且开启runLoop
[[NSRunLoop currentRunLoop] run];

endif

//子线程里 开启异步
NSString *string = @"http://www.baidu.com";

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:string]] delegate:self];

//[[NSRunLoop currentRunLoop] run];

while (!self.isFinish) {
    NSLog(@"123");
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

}

-(void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response
{
NSLog(@”%@”,NSStringFromSelector(_cmd));
}

-(void)connection:(NSURLConnection )connection didFailWithError:(NSError )error
{
NSLog(@”%@”,NSStringFromSelector(_cmd));
}

-(void)connection:(NSURLConnection )connection didReceiveData:(NSData )data
{
NSLog(@”%@”,NSStringFromSelector(_cmd));
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@”%@”,NSStringFromSelector(_cmd));
self.isFinish = YES;
}

-(void)timeChange
{
NSLog(@”123”);
}

main.m

int main(int argc, char * argv[]) {
@autoreleasepool {
//点击事件 InputEvent
//timer TimerEvent
//Oberveser KVO connection
// while (1) {
//
// }
//NSRunLoop

    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值