前言
前段时间一直在面试,整理了不少东西,不仅有基础还有知识的深入,毕竟现在的行业情况不比三年前第一次找工作的时候了。。。希望对他人有所帮助,都能找到一个合适的工作!
一、面试题
让 BAT 的 Offer 不再难拿
[iOS]关于面试,做一次整理吧(包含BAT面试题目)
iOS面试必看,最全梳理
《招聘一个靠谱的 iOS》—参考答案(上)
《招聘一个靠谱的 iOS》—参考答案(下)
二、基础常识
2.1 进程
进程与线程的一个简单解释
DNS 原理入门
计算机是如何启动的?
2.2 沙盒文件夹
- 沙盒文件夹的存取操作
应用沙盒结构分析沙盒文件的结构:(三个文件夹,Document,Library,tmp)。
应用程序包
:包含了所有的资源文件和可执行文件
Documents
:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录[NSBundle mainBundle]
tmp
:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录
Library/Caches
:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据
Library/Preference
:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录(NSUserDefault plist生成的文件)
2.3 Base-64编码
- Base-64编码保证了二进制数据的安全
Base-64编码可以将任意一组字节转换为较长的常见文本字符序列,从而可以合法地作为首部字段值。Base-64编码将用户输入或二进制数据,打包成一种安全格式,将其作为HTTP首部字段的值发送出去,而无须担心其中包含会破坏HTTP分析程序的冒号、换行符或二进制值。Base-64编码是作为MIME多媒体电子邮件标准的一部分开发的,这样MIME就可以在不同的合法电子邮件网关之间传输富文本和任意的二进制数据里。Base-64编码与将二进制数据文本化表示的uuencode和BinHex标准在本质上类似,但空间效率更高。
2.3 写一个iOS应用之前必须做的7件事
- 在写一个iOS应用之前必须做的7件事(附相关资源)
2.4 iOS 申请证书与发布流程
最新的 iOS 申请证书与发布流程(2016.12)
iOS 证书申请和使用详解(详细版)
2.5 OOA、OOD、OOP
oo
:面向对象,个人理解简言之就是设计出来的东西别人很容易理解和使用。
比如你设计(oop)出来的方法类,我只管调用接口,不需要知道内部实现原理,怎么封装的不管。
OOA
:(Object Oriented Analysis)面向对象分析方法。
OOD
:(Object Oriented Design)面向对象设计。
OOP
:(Object Oriented Programming)面向对象(类)的程序设计。
OOP(面向对象编程)的三大特性:
封装:就是将一个类使用和实现分开,只保留部分接口和方法与外部联系 。
继承:子类自动继承其父级类中的属性和方法,并可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。
多态:多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,多态性增强了软件的灵活性。
OOA、OOD、OOP - 小波随笔-iOS开发
iOS - 对OOA、OOD、OOP的理解
OOA/OOD/OOP细讲
2.6 高内聚低耦合
内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系;
耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。
- 高内聚低耦合
三、基础知识点
3.1 UIViewController的生命周期
UIViewController的生命周期总结
关于iOS 中UIViewController的生命周期以及相关视图(View)的探讨
UIViewController的生命周期
ViewController出现后,push出BViewController,BViewController返回d奥ViewController。两个ViewController生命周期如下:
3.2 UIView的生命周期
- UIView的生命周期
这俩个方法可以根据参数是否为nil判断是创建操作还是销毁操作,nil则为销毁,反之,则为创建:
- (void)willMoveToSuperview:(nullable UIView *)newSuperview;
- (void)willMoveToWindow:(nullable UIWindow *)newWindow;
这个方法可以根据self.superview的值判定,nil则为销毁,反之,则为创建:
- (void)didMoveToSuperview;
这个方法可以根据self.superview的值判定,nil则为创建,反之,则为销毁。(注意这个方法和上面的是相反的):
- (void)didMoveToWindow;
使用:
- (void)willMoveToWindow:(UIWindow *)window {
[super willMoveToWindow:window];
// 走到该方法时:window为nil时为销毁;反之,则为创建
if (window) {
return;
}
// 销毁前,移除所有KVO观察
[_leftSliderView removeObserver:self forKeyPath:@"frame" context:NULL];
[_leftSliderView removeObserver:self forKeyPath:@"center" context:NULL];
[_rightSliderView removeObserver:self forKeyPath:@"frame" context:NULL];
[_rightSliderView removeObserver:self forKeyPath:@"center" context:NULL];
}
3.2 UIView的LayouSubviews和drawRect
- UIView的layoutSubviews和drawRect
3.3 NSCoding
- NSCoding / NSKeyedArchiver
·Archiving non-NSCoding-compatible Classes:根据面向对象设计原则,对象应该可以被编码和解码成一种序列化的格式。但是如果一个类不是内置遵循NSCoding,你可以后续让这个类遵循NSCoding来达到目的。
NSCoding
是一个简单的协议,有两个方法: -initWithCoder:
和 -encodeWithCoder:
。遵循NSCoding协议的类可以被序列化和反序列化,这样可以归档到磁盘上或分发到网络上。
NSKeyedArchiver
和NSKeyedUnarchiver
提供了很方便的API把对象读取/写入磁盘。
NSCoding
跟其他存储方式略有不同,他可以存储对象
对象存储的条件是: 对象需要遵守 NSCoding 协议
存储的时候需要 调用 encodeWithCoder 方法
读取的时候需要调用initWithCoder 方法
[NSKeyedArchiver archiveRootObject:stu toFile:path]; // 存储
[NSKeyedUnarchiver unarchiveObjectWithFile:path]; // 读取
——NSCoder的具体子类使用NSCoder抽象类的接口在内存和其他格式之间转换对象和其他数据值,NSCoder可以提供基本的归档——把对象和数据存储在磁盘上,和分配——在不同进程和线程之间复制对象和其他数据。在Foundation框架中会提供NSCoder具体的子类,如:NSArchiver、NSUnarchiver、NSKeyedArchiver、NSKeyUnarchiver和NSPortCoder。NSCoder具体的子类统一称作:编码器类,他们的实例化对象则成为编码器对象,一个编码器对象如果只编码就称做:编码对象,一个编码器对象如果只解码就称作解码对象。
——概述
——NSCoder可以操作对象、标量、C数组、结构体和字符串,还有这些类型的指针。它不能操作的类型是那些跨平台执行的变量,例如:union、void *、函数指针和长链表的指针。
——一个编码器对象储存object类型的信息连同object的数据,因此,一个从字节流解码的对象通常跟最初编码的对象是同一个类。然而,一个对象可以在编码的时候改变它的类;这是描述归档文件和序列化的编程指南。
3.4 Core Data
Core Data入门
iphone数据存储之-- Core Data的使用(一)
Core Data
是数据持久化存储的最佳方式。数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型。
好处:能够合理管理内存,避免使用sql的麻烦,高效
构成:
(1)NSManagedObjectContext
(被管理的数据上下文)
操作实际内容(操作持久层)。
作用:插入数据,查询数据,删除数据
(2)NSManagedObjectModel
(被管理的数据模型)
数据库所有表格或数据结构,包含各实体的定义信息。
作用:添加实体的属性,建立属性之间的关系。
操作方法:视图编辑器,或代码。
(3)NSPersistentStoreCoordinator
(持久化存储助理)
相当于数据库的连接器。
作用:设置数据存储的名字,位置,存储方式,和存储时机。
(4)NSManagedObject
(被管理的数据记录)
相当于数据库中的表格记录。
(5)NSFetchRequest(
获取数据的请求)
相当于查询语句。
(6)NSEntityDescription
(实体结构)
相当于表格结构。
(7)后缀为.xcdatamodeld
的包
里面是.xcdatamodel文件,用数据模型编辑器编辑,
编译后为.momd或.mom文件。
3.5 oc中protocol、category和继承的区别
- oc中protocol、category和继承的区别
3.6 事件分发机制
- iOS开发系列——UIView专题之四:事件分发机制篇【整理,部分原创】
3.7 浅复制和深复制
iOS 集合的深复制与浅复制
小结iOS中的copy
Copy:
- 因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.
- 如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.
copy 此特质所表达的所属关系与 strong 类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为 NSString 时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个 NSMutableString 类的实例。这个类是 NSString 的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。
在非集合类对象中:对immutable对象进行copy操作,是指针复制,mutableCopy操作时内容复制;对mutable对象进行copy和mutableCopy都是内容复制。用代码简单表示如下:
[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //深复制
[mutableObject copy] //深复制
[mutableObject mutableCopy] //深复制
在集合类对象中:对immutable对象进行copy,是指针复制,mutableCopy是内容复制;对mutable对象进行copy和mutableCopy都是内容复制。但是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。用代码简单表示如下:
[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //单层深复制
[mutableObject copy] //单层深复制
[mutableObject mutableCopy] //单层深复制
3.8 arc mrc
iOS中arc的设置与使用-fobjc-arc
或者-fno-objc-arc
。
3.9 objc_setAssociatedObject/objc_getAssociatedObject
- objc_setAssociatedObject/objc_getAssociatedObject
#import
- (void)setName:(NSString *)newName {
objc_setAssociatedObject(self, @selector(name), newName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name {
return objc_getAssociatedObject(self, @selector(name));
}
3.10 什么时候会报unrecognized selector的异常?
《招聘一个靠谱的 iOS》—参考答案(上)第23题
《招聘一个靠谱的 iOS》—参考答案(下)第25题
什么时候会报unrecognized selector的异常?
3.11 对象的内存销毁时间表
- 《招聘一个靠谱的 iOS》—参考答案(上)第18题
// 对象的内存销毁时间表
// http://weibo.com/luohanchenyilong/ (微博@iOS程序犭袁)
// https://github.com/ChenYilong
// 根据 WWDC 2011, Session 322 (36分22秒)中发布的内存销毁时间表
1. 调用 -release :引用计数变为零
* 对象正在被销毁,生命周期即将结束.
* 不能再有新的 __weak 弱引用, 否则将指向 nil.
* 调用 [self dealloc]
2. 子类 调用 -dealloc
* 继承关系中最底层的子类 在调用 -dealloc
* 如果是 MRC 代码 则会手动释放实例变量们(iVars)
* 继承关系中每一层的父类 都在调用 -dealloc
3. NSObject 调 -dealloc
* 只做一件事:调用 Objective-C runtime 中的 object_dispose() 方法
4. 调用 object_dispose()
* 为 C++ 的实例变量们(iVars)调用 destructors
* 为 ARC 状态下的 实例变量们(iVars) 调用 -release
* 解除所有使用 runtime Associate方法关联的对象
* 解除所有 __weak 引用
* 调用 free()
3.11 输出
NSLog(@"类名与方法名:%s(在第%d行),描述:%@", __PRETTY_FUNCTION__, __LINE__, self.lastName);
NSStringFromSelector(_cmd)
3.12 NSTimer和RunLoop
timerWithTimeInterval:target:selector:userInfo:repeats:
:不直接启动,因为没有加入RunLoop,需要手动加入RunLoop才启动。
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
自动加入RunLoop,直接启动。
NSTimer 两种常用创建方式的区别
将NSTimer添加至RunLoop中的两种方法区别
3.13 imageNamed:和imageWithContentOfFile:
- iOS中imageNamed:和imageWithContentOfFile:的区别
使用
imageNamed:
加载图片:
加载到内存中后,会一直停留在内存中,不会随着对象销毁而销毁
加载进图片后,占用的内存归系统管理,我们无法管理
相同的图片,图片不会重新加载
加载到内存中后,占据内存空间较大
使用
imageWithContentOfFile:
加载图片:
加载到内存中后,占据内存空间比较小
相同的图片会被重复加载到内存中
对象销毁的时候,加载到内存中得图片会被一起销毁
3.14 NSDateFormatter性能问题
- NSDateFormatter最佳实践
最佳实践应该是,在工程中添加一个NSDateFormatter的单例对象供全工程使用。
3.15 KVC的keyPath中的集合运算符
// 数组KVC:KVC的keyPath中的集合运算符:@avg,@count,@max,@min,@sum
NSArray * array = @[@3, @1, @2];
NSNumber * max = [array valueForKeyPath:@"@max.intValue"];
3.16 XML/JSON数据解析
XML/JSON数据解析
ios解析XML和son数据
Json格式:
NSJSONSerialization
:官方提供的Json数据格式解析类,iOS5以后支持;
JSONKit(第三方类库)
SBJson
TouchJson
XML格式:
NSXMLParse
:官方自带
GDataXML:Google提供的开元XML解析库
四、Block
block没那么难(一):block的实现
block没那么难(二):block和变量的内存管理
block没那么难(三):block和对象的内存管理
五、ReactiveCocoa
最快让你上手ReactiveCocoa之基础篇
最快让你上手ReactiveCocoa之进阶篇
响应式编程思想:不需要考虑调用顺序,只需要知道考虑结果,类似于蝴蝶效应,产生一个事件,会影响很多东西,这些事件像流一样的传播出去,然后影响结果,借用面向对象的一句话,万物皆是流。
代表:KVO运用。
MVVM介绍:
模型(M):保存视图数据。
视图+控制器(V):展示内容 + 如何展示
视图模型(VM):处理展示的业务逻辑,包括按钮的点击,数据的请求和解析等等。
ReactiveCocoa常见宏:
- RAC(TARGET, [KEYPATH, [NIL_VALUE]]):用于给某个对象的某个属性绑定。
// 只要文本框文字改变,就会修改label的文字
RAC(self.labelView,text) = _textField.rac_textSignal;
- RACObserve(self, name):监听某个对象的某个属性,返回的是信号。
[RACObserve(self.view, center) subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
六、多线程
6.1 线程死锁
- 《iOS多线程编程——GCD与NSOperation总结》
在使用GCD的过程中,如果向当前串行队列中同步派发一个任务,就会导致死锁。
彻底搞懂OC中GCD导致死锁的原因和解决方案
五个案例让你明白GCD死锁
GCD(六)dispatch_semaphore_t signal信号量学习总结.
6.2 同步锁
atomic:给属性的getter和setter加锁,不完全安全,例如array的add、remove等操作的影响就不受保护。
更高效的同步锁-GCD 同步锁
iOS多线程-各种线程锁的简单介绍
[iOS] 正确使用多线程同步锁 @synchronized()
6.3 GCD和NSTimer
- 选择 GCD 还是 NSTimer ?
6.4 GCD和NSOprationQueue
- NSOprationQueue 与 GCD 的区别与选用
6.5 看书
看书-PDF:《多线程编程指南》《iOS并发编程指南》
七、Runtime
- 让你快速上手Runtime
简介:
RunTime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制。
对于C语言,函数的调用在编译的时候会决定调用哪个函数。
对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。
作用:发送消息;交换方法;动态添加方法;给分类添加属性;字典转模型。
Objective-C Runtime
Objective-C Runtime 运行时之一:类与对象
Objective-C Runtime 运行时之二:成员变量与属性
Objective-C Runtime 运行时之三:方法与消息
Objective-C Runtime 运行时之四:Method Swizzling
Objective-C Runtime 运行时之五:协议与分类
Objective-C Runtime 运行时之六:拾遗
- Runtime全方位装逼指南
八、RunLoop
- 深入理解RunLoop
XNU 内核的内环被称作 Mach,其作为一个微内核,仅提供了诸如处理器调度、IPC (进程间通信)等非常少量的基础服务。
RunLoop 的核心是基于 mach port 的,其进入休眠时调用的函数是 mach_msg()。
RunLoop 的核心就是一个 mach_msg() (见上面代码的第7步),RunLoop 调用这个函数去接收消息,如果没有别人发送 port 消息过来,内核会将线程置于等待状态。
苹果用 RunLoop 实现的功能:
AutoreleasePool;事件响应;手势识别;界面更新;定时器;PerformSelecter;关于GCD;关于网络请求。
RunLoop 的实际应用举例:AFNetworking;AsyncDisplayKit。
- iOS开发-Runloop详解
九、HTTP、TCP/IP、Socket
我的博客:TCP/IP、Http、Socket以及UDP
十、直播
【如何快速的开发一个完整的iOS直播app】
【如何快速的开发一个完整的iOS直播app】(采集篇)
【如何快速的开发一个完整的iOS直播app】(美颜篇)
【如何快速的开发一个完整的iOS直播app】(搭建Socket即时通讯服务器)
【如何快速的开发一个完整的iOS直播app】(推流篇)
【如何快速的开发一个完整的iOS直播app】(播放篇)
【如何快速的开发一个完整的iOS直播app】(编解码原理)
直播预览层添加滤镜效果(CIFilter使用场景)
十一、动画
1.1 CAAnimation
ios核心动画高级技巧
iOS开发系列--让你的应用“动”起来
CAAnimation
:核心动画的基础类,不能直接使用,负责动画运行时间、速度的控制,本身实现了CAMediaTiming
协议。
CAPropertyAnimation
:属性动画的基类(通过属性进行动画设置,注意是可动画属性),不能直接使用。
CAAnimationGroup
:动画组,动画组是一种组合模式设计,可以通过动画组来进行所有动画行为的统一控制,组中所有动画效果可以并发执行。
CATransition
:转场动画,主要通过滤镜进行动画效果设置。
CABasicAnimation
:基础动画,通过属性修改进行动画参数控制,只有初始状态和结束状态。
CAKeyframeAnimation
:关键帧动画,同样是通过属性进行动画参数控制,但是同基础动画不同的是它可以有多个状态控制。
基础动画、关键帧动画都属于属性动画,就是通过修改属性值产生动画效果,开发人员只需要设置初始值和结束值,中间的过程动画(又叫“补间动画”)由系统自动计算产生。和基础动画不同的是关键帧动画可以设置多个属性值,每两个属性中间的补间动画由系统自动完成,因此从这个角度而言基础动画又可以看成是有两个关键帧的关键帧动画。
1.2 CADisplayLink
- CADisplayLink
CADisplayLink
是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。我们在应用中创建一个新的 CADisplayLink 对象,把它添加到一个runloop中,并给它提供一个 target 和selector 在屏幕刷新的时候调用。
CADisplayLink 与 NSTimer 有什么不同:iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。
NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。
CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。
十二、性能优化
- 微信读书 iOS 性能优化总结
十三、工具
Git 教程
Masonry介绍与使用实践(快速上手Autolayout)
JSPatch 平台介绍
JSPatch 基础用法
JSPatch实现原理详解
十四、Swift
- The Swift Programming Language 中文版
(我是下载在本地用iBooks看,方便标注)
- InfoQ Swift
十五、React Native
- React Native学习
十六、智能家居
iOS端智能家居WiFi通信
如何动手打造属于自己的智能家居
APP开发第一难点数据通信,要求发送命令到中转器(控制器),由中转器发送命令来控制智能设备,这是一种方式。也有不通过中转器而直接控制智能设备的,实现方式都差不多。数据通信需要定义报文协议,根据报文协议进行数据通信即可,注意高低位问题,注意字节对齐问题。然后商定通讯协议如果用TCP iOS里可以使用AsyncSocket第三方类库,如果用UDP可以 iOS可以使用asyncudpsocket第三方类库。
APP开发智能家居蓝牙通信,目前一般使用蓝牙4.0 BLE通信协议,蓝牙4.0推动了移动智能设备的发展。目前在iPhone4s以上设备才能支持BLE,Android在4.4之后才开始支持BLE。开发者要做的就是熟悉在不同系统平台上的封装API,然后专心业务逻辑处理。
十七、 REST
深入浅出REST
REST API详解