分享

ios - run loop (timer)

 quasiceo 2015-04-18

在ios开发多线程程序的时候,往往会碰到run loop。

对于run loop, 苹果开发网站上有非常详细的说明,www.

强烈建议啃下来,不要怕英文。

copy了一下图片:

\

这里就写个Timer sources的简单例子。

系统创建一个线程的时候,就已经默认创建了一个run loop了,除了主线程默认run loop就是运行的,其他的辅助线程虽说已经创建了run loop但是并没有运行。

 

获取线程的run loop对象

 

1
NSRunLoop* loop = [NSRunLoop currentRunLoop];
通过上面简单的代码就可以获取当前线程的run loop对象。

 

 

创建一个定时器

 

1
2
// Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(doFireTimer:) userInfo:nil repeats:YES];
doFireTimer每0.1秒会被调用一次。简单如下:

 

 

1
2
3
4
- (void) doFireTimer:(NSTimer *)timer
{
    NSLog(@doFireTimer, %f, timer.timeInterval);
}

启动run loop

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
NSInteger loopCount = 2;
do
{
    // 启动当前thread的run loop直到所指定的时间到达,在run loop运行时,run loop会处理所有来自与该run loop联系的input sources的数据
    // 对于本例与当前run loop联系的input source只有Timer类型的source
    // 该Timer每隔0.1秒发送触发时间给run loop,run loop检测到该事件时会调用相应的处理方法(doFireTimer:)
    // 由于在run loop添加了observer,且设置observer对所有的run loop行为感兴趣
    // 当调用runUntilDate方法时,observer检测到run loop启动并进入循环,observer会调用其回调函数,第二个参数所传递的行为时kCFRunLoopEntry
    // observer检测到run loop的其他行为并调用回调函数的操作与上面的描述相类似
    [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow: 0.2]];
    // 当run loop的运行时间到达时,会退出当前的run loop,observer同样会检测到run loop的退出行为,并调用其回调函数,第二个参数传递的行为是kCFRunLoopExit.
    --loopCount;
}while(loopCount);

调用runUntilDate函数,这个函数会使当前的run loop运行0.2秒。这里总共调用2次。

 

因为定时器每隔0.1秒发送一个消息,这样每次runUntilDate应该会接受到2次消息。(把0.2改成0.21啥的,应该就是2次,0.2的话还不一定,因为当发送第二次定时器的时候,run loop生命周期也刚刚到,可能第二次不一定能被处理)。

大致的流程就是

1. 定时器发送消息,每隔0.1秒

2. run loop收到消息,调用doFireTimer函数。

运行如下:可以从左边的调用栈里面看到doFireTimer是从run loop里面调用的。

\

 

完整代码如下:只要在主线程里面启动这个线程就可以了。

[NSThread detachNewThreadSelector:@selector(MyThread) toTarget:self withObject:nil];

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- (void) doFireTimer:(NSTimer *)timer
{
    NSLog(@doFireTimer, %f, timer.timeInterval);
}
- (void) MyThread
{
    NSRunLoop* loop = [NSRunLoop currentRunLoop];
     
    // Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(doFireTimer:) userInfo:nil repeats:YES];
    NSInteger loopCount = 2;
    do
    {
        // 启动当前thread的run loop直到所指定的时间到达,在run loop运行时,run loop会处理所有来自与该run loop联系的input sources的数据
        // 对于本例与当前run loop联系的input source只有Timer类型的source
        // 该Timer每隔0.1秒发送触发时间给run loop,run loop检测到该事件时会调用相应的处理方法(doFireTimer:)
        // 由于在run loop添加了observer,且设置observer对所有的run loop行为感兴趣
        // 当调用runUntilDate方法时,observer检测到run loop启动并进入循环,observer会调用其回调函数,第二个参数所传递的行为时kCFRunLoopEntry
        // observer检测到run loop的其他行为并调用回调函数的操作与上面的描述相类似
        [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow: 0.2]];
        // 当run loop的运行时间到达时,会退出当前的run loop,observer同样会检测到run loop的退出行为,并调用其回调函数,第二个参数传递的行为是kCFRunLoopExit.
        --loopCount;
    }while(loopCount);
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多