正文
-
kCFRunLoopDefaultMode(NSDefaultRunLoopMode)
默认 Mode,主线程一般都是在这个 Mode 下。
-
UITrackingRunLoopMode
界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响。
-
UIInitializationRunLoopMode
在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用。
-
GSEventReceiveRunLoopMode
接受系统事件的内部 Mode,通常用不到。
-
kCFRunLoopCommonModes
不常用
我们根据不同的情况来选择吧定时器加入到model中,也明白了为什么滚动的时候定时器停止,因为默认的时候是加在NSDefaultRunLoopMode上的,但是当tableview或者滚动试图滚动的时候触发的是UITrackingRunLoopMode所以定时器停止了,只有滚动停止切换到NSDefaultRunLoopMode上时定时器继续。
但是为什么最后加到了NSRunLoopCommonModes一样解决了问题呢?而且这里的5中model并没有NSRunLoopCommonModes,NSRunLoopCommonModes是什么呢?
NSRunLoopCommonModes并不是一种Mode,而是一种特殊的标记,包含三种mode(kCFRunLoopDefaultMode、NSTaskDeathCheckMode、UITrackingRunLoopMode),添加到NSRunLoopCommonModes中的还没有执行的任务,会在mode切换时,再次添加到当前的mode中,这样就能保证不管当前runloop切换到哪一个mode,任务都能正常执行。并且被添加到NSRunLoopCommonModes中的任务会存储在runloop 的commonModeItems中。
一句代码却包含这么多,至于更深入的底层的知识有空大家自己研究一下吧,进行下一个部分。
#####获取通讯录并处理
首先要设置获取通讯录的权限,如下图
由于系统的不同获取权限以及协议方法的不同,要进行系统的判断,根据iOS9,以及iOS8做出不同的处理。
导入需要的头文件
遵循的代理
<CNContactPickerDelegate,ABPeoplePickerNavigationControllerDelegate>
授权部分的代码
if(UMSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0")) {
//让用户给权限,没有的话会被拒
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusNotDetermined) {
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (error) {
}else
{
CNContactPickerViewController * picker = [CNContactPickerViewController new];
picker.delegate = self;
picker.displayedPropertyKeys = @[CNContactPhoneNumbersKey];//只显示手机号
[self presentViewController: picker animated:YES completion:nil];
}
}];
}
if