一、代码重构基本思想
1.工作分块细化
2.小功能注意封装,大功能注意模块化
3.项目文件结构分层要明晰
4.命名可读化
3.iCloud同步特性
概念:iCloud是苹果提供的云端服务,用户可以将通讯录、备忘录、邮件、照片、音乐、视频等备份到云服务器并在各个苹果设备间直接进行共享而无需关心数据同步问题,甚至即使你的设备丢失后在一台新的设备上也可以通过Apple ID登录同步。
苹果已经将云端存储功能开放给开发者,可以存储两类数据:
1.key-value data: 分享小量的非关键配置数据到应用的多个实例,使用类似于NSUserDefault.
2.document: 存储用户文档和应用数据到用户的iCloud账户
Cloud Kit :更像是一个数据库,苹果会提供一个dashboard作为云存储的管理端。
Cloud Kit 基础cloud kit一共有7个基础类
1.CKContainer:类似于应用运行时的沙盒,一个应用只能访问自己的沙盒,同样的,一个应用也只能访问自己的Container。
2.CKDatabase:很明显就是数据库,他拥有私有数据库和公有数据库两种类型。用户只能访问自己的私有数据库,一些不敏感的数据也可以存储在公有数据库中。
3.CKRecord:就是数据库中的一条数据记录,他通过key-value的方式来存储和获取数据。
4.CKRecordZone:是用来保存Record的。所有的Record都是保存在这里,应用有一个默认的zone,也可以自定义zone。
5.CKRecordIdentifier:是Record的唯一标示,用来确定Record在数据库中的位置。
6.CKReference:是一种引用关系。
7.CKAsset: 为资源文件,比如之前提到的照片就是用这种方式存储的。
4.OC是动态语言,主要体现在哪里?
OC常见的动态特性分为:动态类型(Dynamic typing),动态绑定(Dynamic binding),动态加载(Dynamic loading)
所谓运行时特性即只有在运行时才会进行具体准确识别的特性
动态类型:运行(时)后再决定对象的真正类型.
动态绑定:即在实例对象所真正归属类确定之后,将该类下某些属性和相应的方法绑定到真正的类的实例对象上。属性和方法既包括类中实现的实现方法也包括非类中实现方法
动态绑定基于动态类型的,在某个实例对象被确定后,其类型便被确定了。其确定类型下对应的属性和响应的消息(消息的响应)也完全确定。传统函数一般在编译时就已经把参数信息和函数的实现打包到编译后的源码二进制文件中,OC中并没有将方法名与方法参数信息编译进入二进制文件中,运行时oc中使用消息机制调用实例方法即向该实例指针发送消息,实例指针在收到消息后,从自身的实现文件中寻找响应消息的方法。
动态加载:根据对资源的实际需求进而加载相应的资源 ,可实现内存的优化.(不同机型适配加载@2x图片,@1x原图)
5.OC的消息转发机制是什么样的?
本质使用runtime进行的方法替换,代码编译完之后,都会转化成C语言的代码在运行时系统上运行;
方法的调用主要是通过objc_msgSend(...)方法簇完成的;objc_msgSend接收一个消息并调用的过程:消息的接收者如果本身类结构中存在这个方法,就会直接被调用,不存在就在父类中寻找,直到最终成功调用或者抛出unrecognized selector;
第二轮面试
1.Runloop是什么概念,有什么作用?
Runloop:运行循环,即死循环。在应用需要的时候跑起来运行,在用户没有操作的时候停下来休息,充分节省CPU资源,提高程序性能。
一般来说,一个线程一次只能执行一个任务,执行完成后线程就回退出,但是有时候我们需要线程能够一直“待命”随时处理事件而不退出,这就需要一个机制来完成这样的任务。
Runloop作用:
1.保持程序持续运行:例如程序一启动就会开一个主线程,主线程一开起来就会跑一个主线程对应的RunLoop,RunLoop保证主线程不会被销毁,也就保证了程序的持续运行;
2.处理App中的各种事件(比如:触摸事件,定时器事件,Selector事件等 );
3.节省CPU资源,优化程序性能:程序运行起来时,当什么操作都没有做的时候,RunLoop就通知系统,现在没有事情做,然后进行休息待命状态,这时系统就会将其资源释放出来去做其他的事情。当有事情做,也就是一有响应的时候RunLoop就会立马起来去做事情;
RunLoop,最重要的作用,也就是用来管理线程的。可以说,没有线程,也就没有RunLoop的存在必要。当线程的RunLoop一开启,RunLoop便开始对线程进行管理工作:在线程执行完任务后,线程便会进入休眠状态,并且不会退出,随时等待新的任务。
一个 RunLoop 包含若干个 Mode,每个 Mode 又包含若干个 Source/Timer/Observer。
每次调用 RunLoop 的主函数时,只能指定其中一个 Mode,这个Mode被称作 CurrentMode。如果需要切换 Mode,只能退出 Loop,再重新指定一个 Mode 进入。这样做主要是为了分隔开不同组的 Source/Timer/Observer,让其互不影响。
6.网络请求用的是什么协议,网络开源库用的是哪个,内部的原理。
网络请求用过HTTP/HTTPS和Socket协议
AFNetworking:并没有为每一个请求创建一个线程,而是将每个请求封装成一个NSOperation放到一个queue.每当该operation执行时,它都会在一个单独的线程中创建NSURLConnection对象,并监听所有的回调。由于网络请求都是采用NSURLConnection或者NSURLSession的异步API,因此一个单一的处理线程已经可以满足需要。
总之:AFNetworking其实是采用了NSOperationQueue+NSURLFoundation的异步API来完成高效的网络请求。
7.如何设置和获取请求的cookies?
ios的cookies存取
8.平时开发中数据库用的是哪个,如何实现读写隔离的?
现在移动端的数据库主要分两个,SQLite和Realm,平时用的是SQLite;说了一下SQLite通过GCD的一些API如何去实现读写隔离,主要是通过dispatch_barrier_async等隔离操作的API去实现;
9.如何保证线程安全
10.如何进行线程间通信
在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信
线程间通信的体现
一:1个线程传递数据给另1个线程
二:在1个线程中执行完特定任务后,转到另1个线程继续执行任务
例1:
回到主线程执行,执行self的showImage方法,参数是image
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
回到xx线程执行aSelector方法,参数是arg
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;