iOS面试专题iOS - 线程/底层/Runtime知识总结

可能碰到的iOS笔试面试题(15)--Runloop

2016-05-04  本文已影响5037人  b485c88ab697

Runloop

什么是 Runloop?

Runloop对象

iOS中有2套API来访问和使用RunLoop

Runloop与线程

获得RunLoop对象

[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象

[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象

CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象

CFRunLoopGetMain(); // 获得主线程的RunLoop对象

RunLoop相关类

Core Foundation中关于RunLoop的5个类
CFRunLoopRef
CFRunLoopModeRef
CFRunLoopSourceRef
CFRunLoopTimerRef
CFRunLoopObserverRef

CFRunLoopModeRef

CFRunLoopModeRef代表RunLoop的运行模式。
一个RunLoop包含若干个Mode,每个Mode又包含若干个(set)Source/(array)Timer/(array)Observer

每次RunLoop启动时,只能指定其中一个 Mode,这个Mode被称作CurrentMode

如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入

这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响

mode主要是用来指定事件在运行循环中的优先级的,分为:
•   NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
•   UITrackingRunLoopMode:ScrollView滑动时会切换到该Mode
•   UIInitializationRunLoopMode:run loop启动时,会切换到该mode
•   NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
苹果公开提供的Mode有两个:
•   NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
•   NSRunLoopCommonModes(kCFRunLoopCommonModes)

CFRunLoopTimerRef

CFRunLoopSourceRef

CFRunLoopSourceRef是事件源(输入源)
按照官方文档,Source的分类
Port-Based Sources
Custom Input Sources
Cocoa Perform Selector Sources
按照函数调用栈,Source的分类
Source0:非基于Port的
Source1:基于Port的,通过内核和其他线程通信,接收、分发系统事件

CFRunLoopObserverRef

    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
    NSLog(@"----监听到RunLoop状态发生改变---%zd", activity);
});

// 添加观察者:监听RunLoop的状态
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);

// 释放Observer
CFRelease(observer);

RunLoop处理逻辑

Runloop的应用

runloop定时源和输入源 imageimage

NSRunLoop的实现机制,及在多线程中如何使用

- 实现机制:回答runloop的基本作用,处理逻辑,前面都有。

- 程序创建子线程的时候,才需要手动启动runloop。主线程的runloop已经默认启动。

- 在多线程中,你需要判断是否需要runloop。如果需要runloop,那么你要负责配置runloop并启动。你不需要在任何情况下都去启动runloop。比如,你使用线程去处理一个预先定义好的耗时极长的任务时,你就可以无需启动runloop。Runloop只在你要和线程有交互时才需要

runloop和线程有什么关系?

- 主线程的run loop默认是启动的。
iOS的应用程序里面,程序启动后会有一个如下的main()函数
( argc,  * argv[]) {
@autoreleasepool {
    return UIApplicationMain(argc, argv, , NSStringFromClass([AppDelegate class]));
}
}
重点是UIApplicationMain()函数,这个方法会为main thread设置一个NSRunLoop对象,这就解释了:为什么我们的应用可以在无人操作的时候休息,需要让它干活的时候又能立马响应。

- 对其它线程来说,runloop默认是没有启动的,runloop只在你要和线程有交互时才需要。

- 在任何一个 Cocoa 程序的线程中,都可以通过以下代码来获取到当前线程的 run loop 。
NSRunLoop *runloop = [NSRunLoop currentRunLoop];

autorelease 对象在什么情况下会被释放?

对于runloop的理解不正确的是

A 每一个线程都有其对应的RunLoop
B 默认非主线程的RunLoop是没有运行的
C 在一个单独的线程中没有必要去启用RunLoop
D 可以将NSTimer添加到runloop中

runloop的mode作用是什么?

mode主要是用来指定事件在运行循环中的优先级的,分为:
•   NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
•   UITrackingRunLoopMode:ScrollView滑动时会切换到该Mode
•   UIInitializationRunLoopMode:run loop启动时,会切换到该mode
•   NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
苹果公开提供的Mode有两个:
•   NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
•   NSRunLoopCommonModes(kCFRunLoopCommonModes)
如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。当我们滚动的时候,也希望不调度,那就应该使用默认模式。但是,如果希望在滚动时,定时器也要回调,那就应该使用common mode。

请写出NSTimer使用时的注意事项(两项即可)

思路和上一题一样,如果想要销毁timer,则必须先将timer置为失效,否则timer就一直占用内存而不会释放。造成逻辑上的内存泄漏。该泄漏不能用xcode及instruments测出来。 另外对于要求必须销毁timer的逻辑处理,未将timer置为失效,若每次都创建一次,则之前的不能得到释放,则会同时存在多个timer的实例在内存中。
参考答案:
•   注意timer添加到runloop时应该设置为什么mode
•   注意timer在不需要时,一定要调用invalidate方法使定时器失效,否则得不到释放

UITableViewCell上有个UILabel,显示NSTimer实现的秒表时间,手指滚动cell过程中,label是否刷新,为什么?

和上一题一样的思路,如果要cell滚动过程中定时器正常回调,UI正常刷新,那么要将timer放入到CommonModes下,因为是NSDefaultRunLoopMode,只有在空闲状态下才会回调。

为什么 UIScrollView 的滚动会导致 NSTimer 失效?

 //将timer添加到NSDefaultRunLoopMode中
 [NSTimer scheduledTimerWithTimeInterval: target: selector:@selector(timerTick:) userInfo: repeats:];
  //然后再添加到NSRunLoopCommonModes里
   NSTimer *timer = [NSTimer timerWithTimeInterval: target: selector:@selector(timerTick:) userInfo: repeats:];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?

在开发中如何使用RunLoop?什么应用场景?

文章如有问题,请留言,我将及时更正。

满地打滚卖萌求赞,如果本文帮助到你,轻点下方的红心,给作者君增加更新的动力。

上一篇 下一篇

猜你喜欢

热点阅读