iOS常见面试题总结(一)
一.沙盒
沙盒本质上是一个文件夹,是iOS平台针对每一个安装的的应用在本地生成的一个文件夹,(沙盒文件夹的名字是随机产生的)应用只能访问自身的沙盒文件夹内的内容.
沙盒文件夹下包含三个文件夹:
(1).Document:存储持久化的数据,想要长久存储的信息存储在该文件夹下,但是该文件夹不要太大,不然上传审核通过不了
Library
(1)Caches:存放缓存文件,下载的音频,视频,图片,小说
(2)Preferences:存放用户的偏好设置.比如用户存储的用户名和密码,引导页的是否是第一次启动等(NSUserDefaults存储的内容就在这)
tmp:存放临时文件,比如下载的zip包,当解压完后,zip包将被删除,没有下载完成的音频,视频等,当下载完成之后会从tmp文件夹移动到Caches文件夹
我们可以在这三个文件夹以及其子文件夹内创建文件或者创建文件夹,但是我们只有操作(删除,移动)我们创建的文件夹或者文件权限,系统给我们创建的这三个文件夹我们是没有权限删除或者移动的
二.线程,进程
程序:安装在设备上的每一个应用都是一个程序
进程:每一个正在运行的程序都是一个进程,进程相当于一个任务
线程:执行任务的单元片段叫做线程,是任务的真正执行者,只不过系统默认把所有的任务都交给一个线程去处理(主线程),但是,为了提高程序的运行效率,我们需要把一些耗时的任务交给子线程去处理
线程并发:多个任务在分配线程的时候遵循FIFO的原则,但是多个任务在分配线程完毕之后是同时开始执行的,有可能后分配的任务先完成
线程同步:多个任务直接存在依赖关系,一个任务开始执行需要等到另外一个任务的执行结束,所以,各个任务的执行是有先后顺序的
线程互斥:当多个任务访问同一块资源时,一个线程在访问.其余线程处于等待状态,直到该线程访问完毕,要实现线程互斥需要加锁
线程死锁:资源有加锁的过程但缺少解锁的过程就容易造成线程死锁,一个线程等待另外一个线程释放资源(解锁),但另外一个线程一直没有解锁,则其它线程一直处于等待状态,程序无法继续运行下去
三.创建线程的三种方式
1.NSThread:需要我们手动的进行开启和释放.
2.NSOperation:不需要我们管理,NSOperation是一个抽象类,我们使用的时候一般使用它的子类NSInvocationOperation和NSBlockOperation创建任务,然后放到任务队列NSOperationQueue中执行
3.GCD(共产党):是Apple开发的一个多核编程的解决方法,GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用.
•NSThread:–优点:NSThread 比其他两个轻量级,使用简单–缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销•NSOperation:–不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上–NSOperation是面向对象的•GCD:–Grand Central Dispatch是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术–GCD是基于C语言的
四.常见的数据持久化方法有哪些?
1.NSUserDefaults
2.归档,反归档后的文件写入(归档反归档是将复杂的对象转化成NSData类型,再进行文件的读写操作,归档反归档并不能算是一种数据持久化方式)
3.文件读写
4.SQLite
5.CoreData
6.属性列表(plist)
五.retain cycle例子
1.在该类中定义了block属性,然后在该block块中使用了self,就会造成循环引用.解决方法:使用__block.
2.在该类中定义了代理,但是代理的属性为retain.在代理对象的类中也定义了属性来存储该类的对象,语义特性也是retain,就会造成相互持有,循环引用.
3.在A中定义了B类的对象,语义特性为retain,在B中也定义了A类对象的属性,语义特性为retain.当属性都存储对应的对象时,就产生循环引用.
六.HTTP协议中,GET和POST的区别是什么?
GET请求:参数与网址拼接在一起进行网络请求,安全性低,一般用于请求数据.
POST请求:参数不与网址拼接在一起,单独封装成请求参数,安全性高,一般用于上传数据.
七.支付宝SDK集成步骤
向支付宝申请,与支付宝签约,获取相应的商户ID(partner),账号ID(seller)与私钥(privateKey ),下载支付宝SDK,生成订单信息,签名加密调用支付宝客户端,由支付宝客户端与支付宝服务器打交道,支付完毕后,支付宝客户端会自动跳回原来的应用程序,在原来的应用程序中显示支付结果.
八.远程推送
1.客户端的APP需要将用户的UDID和APP的bundleID发送给APNS进行注册,APNS返回加密的device Token.
2.将APP的device Token发送给公司服务器.
3.当有需要推送的内容时,公司服务器将需要推送的内容和device Token发送给APNS,由APNS将内容推送给用户.
九.平常用的多线程处理方式及优缺点
iOS有四种多线程编程的技术,分别是:NSThread,Cocoa NSOperation,GCD(全称:Grand Central Dispatch).
1)NSThread优点:NSThread 比其他两个轻量级。缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销。
2)Cocoa NSOperation优点:不需要关心线程管理, 数据同步的事情,可以把精力放在自己需要执行的操作上。Cocoa operation相关的类是NSOperation, NSOperationQueue.NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类: NSInvocationOperation和NSBlockOperation.创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。
3)GCD(全优点)Grand Central dispatch(GCD)是Apple开发的一个多核编程的解决方案。在iOS4.0开始之后才能使用。GCD是一个替代NSThread, NSOperationQueue,NSInvocationOperation等技术的很高效强大的技术。
十.runtime
runtime:运行时机制
1.是什么? 1.1runtime是一套比较底层的纯C语言的API,runtime就是一个库,一个C语言库,包含了许多底层的C语言API
1.2平时我们编写的OC代码,在程序运行过程中,其实最终都是转成了runtime的C语言代码,runtime算是OC的幕后工作者,是整个OC的底层
1.3举个例子 // oc中的代码:[Student alloc] init]经过runtime后,其实最终在底层生成C语言代码: // objc_msgSend(objc_msgSend("Student","alloc"), "init") // objc_msgSend其实就是想某个对象发送什么消息,这个函数第一个参数是类型或对象名,第二个参数是消息的名字,这些代码比较底层
2.用过吗?怎么用? // 2.1 runtime是属于OC的底层,可以进行一些非常底层的操作(用OC无法实现的,或者说不好实现)eg // *在程序运行过程中,动态创建一个类,(比如KVO和KVC的底层实现) // *在程序运行过程中,动态为某个类添加属性/方法,修改属性值,修改方法 // *遍历一个类中所有的属性和实例变量和所有方法 // 3. // 3.1相关的头文件 // #import// #import//消息发送机制,可以直接用底层函数,进行消息发送 // 3.2相关应用 // *NSCoding(归档和解挡) // *字典转模型(利用runtime遍历模型对象的所有属性,根据属性名从字典中取出对应的值,设置到模型的属性上) // *kvo(利用runtime动态产生一个类) // 3.3相关函数 // msg_send:给对象发送消息,来自// class_copyMethodList,遍历某个类中所有的方法,来自// class_copyIvarList,遍历某个类中所有的实例变量的方法
// 运行时必备常识:
// 1.Ivar:成员变量的意思
// 2.Method:成员方法的意思
// 3.property:属性
十一。__block和__weak修饰符的区别:
__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
__block对象可以在block中被重新赋值,__weak不可以。
十二。使用单例应注意的事情
单例使用 NSMutableArray 的时候,防止多个地方对它同时遍历和修改的话,需要加原子属性。并且property用strong,并且写一个遍历和修改的方法。加上锁. Lock,UnLock.(PS:考虑性能问题尽量避免使用锁,在苹果的文档张看到的不要问我为什么,我也忘了自己查去。。)
十三。熟悉 CocoaPods 么?能大概讲一下工作原理么?
参考答案:
CocoaPods注意点:CocoaPods在pod install以后会生成一个Podfile.lock的文件,这个文件在多人协作开发的时候就不能加入在.gitignore中,因为这个文件会锁定当前各依赖库的版本,就算之后再pod install也不会更改版本,不提交上去的话就可以防止第三方库升级后造成大家各自的第三方库版本不同
CocoaPods原理:
1.Pods项目最终会编译成一个名为libPods.a的文件,主项目只需要依赖这个.a文件即可
2.对于资源文件,CocoaPods提供了一个名为Pods-resources.sh的bash脚本,该脚本在每次项目编译的时候都会执行,将第三方的各种资源文件复制到目标目录中
3.CocoaPods通过一个名为Pods.xcconfig的文件在编译时设置所有的依赖和参数
十四。你一般是怎么用 Instruments 的?
参考答案:
1.Time Profiler:性能分析
2.Zombies:检查是否访问了僵尸对象,但是这个工具只能从上往下检查,不智能
3.Allocations:用来检查内存,写算法的那批人也用这个来检查
4.Leaks:检查内存,看是否有内存泄露