iOS面试题总结
内存的理解
C语言程序的内存分布1.堆:动态内存 2.栈:函数调用/局部变量 3.全局变量/静态变量 4.机器指令
OC的内存管理使用了“引用计数”的方式。ARC之前内存需要程序员手动的释放创建的对象,当对象引用的时候计数+1,当计数为0时对象释放,但是ARC出现后系统将会为你管理内存,在ARC环境中只 需要明确强引用和弱引用的概念。ARC提 供了四种修饰符__strong __weak __unsafe_unretained __autoreleasing
(1)变量默认都是__strong修饰,可以理解为只要强引用存在,对象就不会释放,当超过了对象的作用域以及没有强引用时,对象会自动销毁。
(2)__weak不持有对象,简单引用,不会阻止对象的销毁,主要是为了防止循环引用出现死循环对象都不释放而引入。
(3)__unsafe_unretained,类似weak,但是不会在没有引用的时候自动设置为nil。
(4)__autoreleasing 用于标识id*的引用参数,或者需要自动释放的返回对象。
详细的ARC苹果文档都有说明和代码的测 试。iOS对内存的利用水平非常高,所以对于内存程序员需要处理的很好,虽然不能完全阻止内存泄漏,但是越少的内存泄漏才能使得APP的安全和运行更好,更流畅。
2.多线程
iOS中多线程使用并不复杂,关键是如何控制各个线程的执行顺序、处理好资源竞争问题。
进程:在内存中占用一定的空间 线程:加载数据UI等的任务模块,在加载数据时出现了耗时的任务时,为了不影响用户体验,衍生出来了多线程,主线程用来处理主体的展示和交互事????件,子线程处理耗时的任务。
三种常见的创建多线程的方式
(1)NSThread:
这套方案是经过苹果封装后的,并且完全面向对象的。所以你可以直接操控线程对象,非常直观和方便。但是,它的生命周期还是需要我们手动管理,所以这套方案也是偶尔用用,比如 [NSThread currentThread],它可以获取当前线程类,你就可以知道当前线程的各种属 xing,用于调试十分方便。
(2)NSOperation/NSOperationQueue
创建NSOperation添加到NSOperationQueue 优点:更加面向对象,可以控制最大并发数即可实现同步和异步;添加任务之间的依赖控制执行顺序。
(3)
1
|
dispatch_async(dispatch_queue_t queue,dispatch_block_t block); |
async表明异步运行,block代表的是你要做的事情,queue则是你把任务交给谁来处理了.
之所以程序中会用到多线程是因为程序往往会需要读取数据,然后更新UI.为了良好的用户体验,读取数据的操作会倾向于在后台运行,这样以避免阻塞主线程.三种queue来处理。
1. Main queue:
顾名思义,运行在主线程,由dispatch_get_main_queue获得.和ui相关的就要使用MainQueue.
2.Serial quque(private dispatch queue)
每次运行一个任务,可以添加多个,执行次序FIFO. 通常是指程序员生成的.
3. Concurrent queue(globaldispatch queue):
可以同时运行多个任务,每个任务的启动时间是按照加入queue的顺序,结束的顺序依赖各自的任务.使用dispatch_get_global_queue获得.
3.KVC和KVO
(1)KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提 供一种机制来间接访问对象的属xing。而不是通过调用Setter、Getter方法访问。KVO 就是基于 KVC 实现的关 键技 术之一。
(2)KVO的是Key Value Observe的缩写,中文是键值观察。这是一个典型的观察者模式,观察者在键值改变时会得到通 知。iOS中有个Notification的机 制,也可以获得通知,但这个机制需要有个Center,相比之下KVO更加简洁而直接。
4.NSNotification、delegate和KVO的区别
(1)效率肯定是delegate比NSNotification高。
(2) delegate方法比notification更加直接,最典型的特征是,delegate方法往往需要关注返回值,需要关心返回的是yes还是no。notification最大的特色就是不关心接受者的态度, 我只管把通告放出来,你接受不接受就是你的事情,同时我也不关心结果。
(3)简明概要的说明了KVO和NSNotification的区别:
和delegate一样,KVO和NSNotification的作用也是类与类之间的通信,与delegate不同的是
1)这两个都是负责发出通知,剩下的事情就不管了,所以没有返回值;
2)delegate只是一对一,而这两个可以一对多。这两者也有各自的特点。
5.类别和扩展还有协议
类别(Category):类别提 供一种不同于继承而给已有类扩展行为的能力,只能增加方法不能增加实例变量。同一个类可以拥有任意多个类别,类别会影响到类的所有子类。(类别不会自动加载)
扩展(Extension):没有自己的实现体可以定义实例变量,用于定义“私有变量”。
协议(Protocol):只能定义接口,而不能实现。有选择实现和必须实现的方法。协议的出现可以理解为协议将类划分为了实现了某个协议的类和没有实现某个协议的类。
6.缓存图片SDWebImage
缓存根据CacheKey查找是否已经缓存,如果已经缓存则会回调加载图片的方法。如果内存过小会先清理内存缓存。如果在硬盘中读取不到图片则需要下载图片,下载图片后解码处理,回调给展示图片的地方同时在内存和硬盘缓存。
7.Socket编程
连接
即时通讯最大的特点就是实时xing,基本感觉不到延时或是掉线,所以必须对socket的连接进行监视与检测,在断线时进行重新连接,如果用户退出登录,要将socket手动关闭,否则对服务器会造成一定的负荷。
一般来说,一个用户(对于iOS也就是我们的项目中)只能有一个正在连接的socket,所以这个socket变量必须是全局的,这里可以考虑使用单例或是AppDelegate进行数据共 xiang,所以使用单例。如果对一个已经连接的socket对象再次进行连接操作,会抛出异常(不可对已经连接的socket进行连接)程序崩溃,所以在连接socket之前要对socket对象的连接状态进行判 断
使用socket进行即时通讯还有一个必须的操作,即对服务器发送心跳包,每隔一段时间对服务器发送长连接指令(指令不唯一,由服务器端指定,包括使用socket发送消息,发送的数据和格式都是由服务器指定),如果没有收到服务器的返回消息,AsyncSocket会得到失去连接的消息,我们可以在失去连接的回调方法里进行重新连接。
断开连接
失去连接有几种情况,服务器断开,用户主动cut,还可能有如Q*其他设备登录被掉线的情况,不管那种情况,我们都能收到socket回调方法返回给我们的讯息,如果是用户退出登录或是程序退出而需要手动cut,我们在cut前对socket的userData赋予一个值来标记为用户退出,这样我们可以在收到断开信息时判 断究竟是什么原因导致的掉线
发送数据
socket发送数据是以栈的形式存放,所有数据放在一个栈中,存取时会出现粘包的现象,所以很多时候服务器在收发数据时是以先发送内容字节长度,再发送内容的形式,得到数据时也是先得到一个长度,再根据这个长度在栈中读取这个长度的字节流,如果是这种情况,发送数据时只 需在发送内容前发送一个长度,发送方法与发送内容一样。
8.XMPP即时通讯
目前IM即时通讯有四种协议IRIM、SIP、XMPP。XMPP是以XML数据类型为基础,即可扩展消息处理现场协议近端串流式即时通信协议。协议内容定义了三种角色客户端、服务端、网 关。能在三者的任意两者之间双向发生。基本的网络形式是单客户端通过TCP/IP连接服务器在上面传输XML。特点C/S通信模式,分布式网络,简单客户端。尽可能的在服务器上面处理数据减少客户端的消耗。通讯数据由服务器转发。
一。大概的连接过程如下
1.运行后需要和服务器建立一个长连接,系统会反馈链接是否成功
2.成功时需要告诉服务器的用户的密码,服务器判 断是否给予授权
3.成功授权后,告诉服务器上线了。
4.将要离开时告诉服务器,我需要断开链接了。
5.服务器反馈你可以断开了,然后你再告诉服务器你下线了
8.单例实例
单例模式就是只有一个实例,确保一个类只有一个实例,并且自行实例化并向整个系统提 供这个实例,一个单例类可以实现在不同的窗口之间传递数据。
在oc中要实现一个单例类,至少需要做以下四个步骤:
1、为单例对象实现一个静态实例,并初始化,然后设置成nil,
2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,
3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例
4、适当实现allocWitheZone,copyWithZone,release和autorelease
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
|
#import <foundation foundation.h> @inter face Singleton : NSOВJect +(instanсеtype) shareInstance ; @end #import "Singleton.h" @implementation Singleton static Singleton* _instance = nil; +(instanсеtype) shareInstance { static dispatch_once_t onсеtoken ; dispatch_once(&onсеtoken, ^{ _instance = [[se lf alloc] init] ; }) ; return _instance ; } @end |
9.AFNeТWorking 的GET和POST请求
1、同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作,所以不推荐。
2、异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然可以对UI进行操作,程序可以继续运行
3、GET请求,将参数直接写在访问路径上。操作简单,不过容易被外界看到,安全xing不高,地址最多255字节;
4、POST请求,将参数放到body里面。POST请求操作相对复杂,需要将参数和地址分开,不过安全xing高,参数放在body里面,不易被捕获
10.数据的持久化方式
属xing列表 NSUserDefaults
对象归档 NSCoding协议
SQLite3 开源的嵌入式关系数据库 FMDB第三方库对此做了封装。
coreData 苹果的数据库框架
11.沙盒机制
iOS沙盒机制:
iOS应用程序只能在为该改程序创建的文件中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属xing列表,文本文件等。
1、每个应用程序都有自己的存储空间
2、应用程序不能翻过自己的围墙去访问别的存储空间的内容
3、应用程序请求的数据都要通过权限检测,假如不符条件的话,不会被放行。
sandbox是一种安全体吅系,应用程序的所有操作都要通过这个体吅系来执行,其中核心内容是:sandbox对应用程序执行各种操作的权限限 制。
目录结构
默认情况下,每个沙盒含有3个文件夹:Documents, Library , tmp和一个.app部分。因为应用的沙盒机制,应用只能在几个目录下读写文件
Documents:苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录
Library:存储程序的默认设置或其它状态信息;
Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
tmp:提 供一个即时创建临时文件的地方。
iTunes在与iPhone同步时,备份所有的Documents和Library文件。
iPhone在重启时,会丢弃所有的tmp文件。
获取沙盒的目录
1
|
NSString *homeDirectory = NSHomeDirectory(); |
获取Cache目录:
1
|
NSArray*paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES); NSString *path = [paths oВJectAtIndex:0];NSLog(@ "%@" , path); |
获取documents目录:
1
|
NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);NSString *path = [paths oВJectAtIndex:0];NSLog(@ "path:%@" , path); |
获取Libarary目录:
1
|
NSArray*paths =NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES);NSString *path = [paths oВJectAtIndex:0];NSLog(@ "%@" , path); |
获取tmp目录:
1
|
NSString*tmpDir = NSTemporaryDirectory(); NSLog(@ "%@" , tmpDir); |
回顾了一下这些天的面试问题,做出了一部分的总结。虽然这些都是很基础的东西,但是人脑的记忆还是没有电 脑厉害。写下自己多看看,积累,学习。这只是一部分。下次总结面试中的进阶问题。推吅送消息机制,上架流程,蓝牙开发,IOS中的WEB开发,PHP,支付SDk等。