iOS知识点大全:html
一.Objc三大特性1.封装2.继承3.多态java
1> 什么是多态ios
多态:不一样对象以本身的方式响应相同的消息的能力叫作多态。c++
因为每一个类都属于该类的名字空间,这使得多态称为可能。类定义中的名字和类定义外的名字并不会冲突。类的实例变量和类方法有以下特色:程序员
方法名是对象接口的一部分。对象收到的消息的名字就是调用的方法的名字。由于不一样的对象能够有同名的方法,因此对象必须能理解消息的含义。一样的消息发给不一样的对象,致使的操做并不相同。web
多态的主要好处就是简化了编程接口。它允许在类和类之间重用一些习惯性的命名,而不用为每个新加的函数命名一个新名字。这样,编程接口就是一些抽象的行为的集合,从而和实现接口的类区分开来。算法
Objective-C支持方法名的多态,但不支持参数和操做符的多态。数据库
2> OC中如何实现多态编程
在Objective-C中是经过一个叫作selector的选取器实现的。在Objective-C中,selector有两个意思, 当用在给对象的源码消息时,用来指方法的名字。它也指那个在源码编译后代替方法名的惟一的标识符。 编译后的选择器的类型是SEL有一样名字的方法、也有一样的选择器。你可使用选择器来调用一个对象的方法。设计模式
选取器有如下特色:
* 全部同名的方法拥有一样的选取器
* 全部的选取器都是不同的
(1) SEL和@selector
选择器的类型是 SEL。@selector指示符用来引用选择器,返回类型是SEL。
例如:
SEL responseSEL;
responseSEL = @selector(loadDataForTableView:);
能够经过字符串来获得选取器,例如:
responseSEL = NSSelectorFromString(@"loadDataForTableView:");
也能够经过反向转换,获得方法名,例如:
NSString *methodName = NSStringFromSelector(responseSEL);
(2) 方法和选取器
选取器肯定的是方法名,而不是方法实现。这是多态性和动态绑定的基础,它使得向不一样类对象发送相同的消息成为现实;不然,发送 消息和标准C中调用方法就没有区别,也就不可能支持多态性和动态绑定。
另外,同一个类的同名类方法和实例方法拥有相同的选取器。
(3) 方法返回值和参数类型
消息机制经过选取器找到方法的返回值类型和参数类型,所以,动态绑定(例:向id定义的对象发送消息)须要同名方法的实现拥有相 同返回值类型和相同的参数类型;不然,运行时可能出现找不到对应方法的错误。
有一个例外,虽然同名类方法和实例方法拥有相同的选取器,可是它们能够有不一样的参数类型和返回值类型。
3> 动态绑定
二.类和对象
1.category
1> 分类拓展协议中哪些能够声明属性?
均可以,但分类和协议建立的属性只至关于方法,可是内部没有对成员变量的操做(没法建立成员变量),拓展能够
代理中声明属性,没有实际建立成员变量,至关于声明了属性名对应的访问方法,遵照协议的类须要实现对应的访问器方法,不然运行报错
分类中声明属性,警告提示须要手动实现访问器方法(Swift中叫计算型属性),而分类中不能建立成员变量,能够在手写访问器方法中使用runtime的 objc_setAssociatedObject方法关联对象间接建立属性(静态库添加属性)
拓展里能够声明属性,直接可使用
2> 继承和类别的区别
1> 使用继承:
1.1> 添加新方法和父类方法一致,但父类方法仍须要使用
1.2> 添加新属性
2> 类别:
2.1> 针对系统提供的一些类,系统自己不提倡继承,由于这些类的内部实现对继承有所限制(NSString initWithFormat继承崩溃)
2.2> 类别能够将本身构建的类中的方法进行分组,对于大型的类,提升可维护性
3> 分类的做用
将类的实现分散到多个不一样文件或多个不一样框架中。
建立对私有方法的前向引用。
向对象添加非正式协议。
4> 分类的局限性
没法向类中添加新的实例变量,类别没有位置容纳实例变量。
名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具备更高的优先级。类别方法将彻底取代初始方法从而没法再使用初始方法。
没法添加实例变量的局限可使用字典对象解决.
2.extension
3.protocol
三.Foundation
1.字符串
2.NSArray和NSDictionary
1> iOS遍历数组/字典的方法
数组: for循环 for in enumerateObjectsUsingBlock(正序) enumerateObjectsWithOptions:usingBlock:(多一个遍历选项,不保证顺序)
字典:
1. for(NSString *object in [testDic allValues])
2. for(id akey in [testDic allKeys]){
[sum appendString:[testDic objectForKey:akey]]; }
3. [testDic enumerateKeysAndObjectsUsingBlock:^(idkey,idobj,BOOL*stop) {
[sum appendString:obj]; } ];
速度: 对于数组, 加强for最快,普通for和block速度差很少,加强最快是由于加强for语法会对容器里的元素的内存地址创建缓冲,遍历的时候直接从缓冲中取元素地址而不是经过调用方法来获取,因此效率高.这也是使用加强for时不能在循环体中修改容器元素的缘由之一(能够在循环体中添加标记,在循环体外修改元素)
对于字典,allValues最快,allKey和block差很少,缘由是allKey须要作objcetForKey的方法
3.NSValue NSNumber
1> 归档视图尺寸,坐标
四.关键字
1.@property
1>readwrite,readonly,assign,retain,copy,nonatomic属性的做用
@property是一个属性访问声明,扩号内支持如下几个属性:
1.1> getter setter
getter=getterName,setter=setterName,设置setter与getter的方法名
1.2> weak assign strong copy
assign 用于非指针变量。用于基础数据类型 (例如NSInteger)和C数据类型(int, float, double, char, 等),另外还有id,其setter方法直接赋值,不进行任何retain操做
weak 用于指针变量,比assign多了一个功能,当对象消失后自动把指针变成nil,因为消息发送给空对象表示无操做,这样有效的避免了崩溃(野指针),为了解决原类型与循环引用问题
strong 用于指针变量,setter方法对参数进行release旧值再retain新值
copy 用于指针变量,setter方法进行copy操做,与retain处理流程同样,先旧值release,再copy出新的对象,retainCount为1。这是为了减小对上下文的依赖而引入的机制。copy是在你不但愿a和b共享一块内存时会使用到。a和b各自有本身的内存。
1.3> readwrite,readonly,设置可供访问级别
1.4> nonatomic,非原子性访问,不加同步,多线程并发访问会提升性能。注意,若是不加此属性,则默认是两个访问方法都为原子型事务访问。因此约定俗成只在主线程更新UI,防止多线程设置UI属性,出现资源抢夺现象
2> 如何避免循环引用
两个对象相互强引用,都没法release,解决办法为一个使用strong,一个使用assign(weak)
3> delegate的属性为何使用assign/weak
避免出现循环引用,场景如UITableViewController强引用视图UITableView,而该视图的代理又是控制器,为避免循环引用,让delegate为弱引用
2.copy
1> copy的使用场景
当多个指针指向同一个对象时,为避免一个指针对对象的改动对其余指针的使用产生影响,使用copy来建立对象的副本
如页面间传值使用copy,A向B控制器传属性(属性为自定义对象),为避免因A的属性变化对B的属性产生影响
再如多人开发或封装库,在不明确传入值为可变仍是不可变的状况下,使用copy更安全
2> 什么是深拷贝浅拷贝
对于非容器类对象,不可变对象进行copy操做为浅拷贝,引用计数器加1,其余三种为深拷贝
对于容器类对象,基本和非容器类对象一致,但注意其深拷贝是对象自己是对象复制,其中元素仍为指针复制,系统将initWithArray方法归为了元素深拷贝,但其实若是元素为不可变元素,仍为指针复制,使用归解档能够实现真正的深拷贝,元素也是对象拷贝NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject: array]];
3> 字符串何时使用copy,strong
属性引用的对象由两种状况,可变和不可变字符串
引用对象不可变状况下,copy和strong同样,copy为浅拷贝
引用对象可变状况下,若是但愿属性跟随引用对象变化,使用strong,但愿不跟随变化使用copy
4> 字符串所在内存区域
@“abc” 常量区 stringwithformat 堆区
5> mutablecopy和copy @property(copy) NSMutableArray *arr;这样写有什么问题
mutablecopy返回可变对象,copy返回不可变对象
6> 如何让自定义类可使用copy修饰符
实现<NSCopying>协议,重写copyWithZone方法
五.runtime/消息转发机制
1.runtime http://www.cocoachina.com/ios/20150715/12540.html
1> 什么是runtime
runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了不少底层的C语言API。
在咱们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工做者,objc_msgSend
2> runtime干什么用,使用场景
runtime是属于OC的底层, 能够进行一些很是底层的操做(用OC是没法现实的, 很差实现)
在程序运行过程当中, 动态建立一个类(好比KVO的底层实现) objc_allocateClassPair,class_addIvar,objc_registerClassPair
在程序运行过程当中, 动态地为某个类添加属性\方法, 修改属性值\方法(修改封装的框架) objc_setAssociatedObject object_setIvar
遍历一个类的全部成员变量(属性)\全部方法(字典转模型,归解档) class_copyIvarList class_copyPropertyList class_copyMethodList
2.消息机制
1> 消息转发的原理
当向一个对象发送消息时,objc_msgSend方法根据对象的isa指针找到对象的类,而后在类的调度表(dispatch table)中查找selector。若是没法找到selector,objc_msgSend经过指向父类的指针找到父类,并在父类的调度表(dispatch table)中查找selector,以此类推直到NSObject类。一旦查找到selector,objc_msgSend方法根据调度表的内存地址调用该实现。 经过这种方式,message与方法的真正实如今执行阶段才绑定。
为了保证消息发送与执行的效率,系统会将所有selector和使用过的方法的内存地址缓存起来。每一个类都有一个独立的缓存,缓存包含有当前类本身的 selector以及继承自父类的selector。查找调度表(dispatch table)前,消息发送系统首先检查receiver对象的缓存。
缓存命中的状况下,消息发送(messaging)比直接调用方法(function call)只慢一点点点点。
2> SEL isa super cmd 是什么
sel: 一种类型,表示方法名称,相似字符串(可互转)
isa:在方法底层对应的objc_msgSend调用时,会根据isa找到对象所在的类对象,类对象中包含了调度表(dispatch table),该表将类的sel和方法的实际内存地址关联起来
super_class:每个类中还包含了一个super_class指针,用来指向父类对象
_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例
IMP定义为 id (*IMP) (id, SEL, …)。这样说来, IMP是一个指向函数的指针,这个被指向的函数包括id(“self”指针),调用的SEL(方法名),再加上一些其余参数.说白了IMP就是实现方法
3> 动态绑定
—在运行时肯定要调用的方法
动态绑定将调用方法的肯定也推迟到运行时。在编译时,方法的 调用并不和代码绑定在一块儿,只有在消实发送出来以后,才肯定被调用的代码。经过动态类型和动态绑定技术,您的代码每次执行均可以获得不一样的结果。运行时因 子负责肯定消息的接收者和被调用的方法。运行时的消息分发机制为动态绑定提供支持。当您向一个动态类型肯定了的对象发送消息时,运行环境系统会经过接收者 的isa指针定位对象的类,并以此为起点肯定被调用的方法,方法和消息是动态绑定的。并且,您没必要在Objective-C 代码中作任何工做,就能够自动获取动态绑定的好处。您在每次发送消息时,特别是当消息的接收者是动态类型已经肯定的对象时,动态绑定就会例行而透明地发生。
六.内存管理
1.内存区域
1>堆和栈的区别
管理方式:对于栈来说,是由编译器自动管理,无需咱们手工控制;对于堆来讲,释放工做由程序员控制,容易产生memory leak。
申请大小:
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就肯定的常数),若是申请的空间超过栈的剩余空间时,将提示overflow。所以,能从栈得到的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是因为系统是用链表来存储的空闲内存地址的,天然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。因而可知,堆得到的空间比较灵活,也比较大。
碎片问题:
对于堆来说,频繁的new/delete势必会形成内存空间的不连续,从而形成大量的碎片,使程序效率下降。对于栈来说,则不会存在这个问题,由于栈是先进后出的队列,他们是如此的一一对应,以致于永远都不可能有一个内存块从栈中间弹出
分配方式:
堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,好比局部变量的分配。动态分配由alloca函数进行分配,可是栈的动态分配和堆是不一样的,他的动态分配是由编译器进行释放,无需咱们手工实现。
分配效率:
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。
2.iOS内存管理
1> 字符串的内存管理
建立字符串的内存空间 堆 常量区
2> 循环引用
delegate属性的内存策略
block循环引用 实际场景
3> autorelease的使用 工厂方法为何不释放对象 ARC下autorelease的使用场景
避免内存峰值
SDWebimage中加载gif图片 大循环
栈结构 栈顶
统一发release消息
4> ARC和MRC的混用
4.1> MRC>ARC
把MRC的代码转换成ARC的代码,删除内存管理操做(手动)
xcode提供了自动将MRC转换成ARC的功能,操做菜单栏edit -> Refacotor(重构) -> Convert to Objective-C ARC
4.2> ARC>MRC
在ARC项目中继续使用MRC编译的类,在编译选项中标识MRC文件便可"-fno-objc-arc"
在MRC项目中继续使用ARC编译的类在编译选项中标识MRC文件便可"-fobjc-arc"
3.跨平台
3> OC和C框架对象引用
oc和c 桥接 三个桥接关键字都是干么的 __bridge 不更改归属权 __bridge_transfer 全部权给OC __bridge_retain 解除OC的全部权
ios5/6/7/8 内存方面的区别?
ios5.自动引用计数 (ARC)
ios6.UICollectionView ( 内存重用机制,图片展现瀑布流实现 ) 在didReceiveMemoryWarning中处理内存(6以前在ViewDidUnload中) http://blog.csdn.net/likendsl/article/details/8199350
ios7.iOS7之后强制使用ARC
ios8
七.数据传递
1.block
1> block属性为何用copy?
栈->堆
2> block使用注意什么?
循环引用 修改外部变量
3> block的主要使用场景 ?
动画
数组字典排序遍历
回调状态
错误控制
多线程GCD
4>block原理
block属性是指向结构体的指针,
2.Delegate
4> 何时用delegate,何时用Notification
delegate针对one-to-one关系,而且reciever能够返回值给sender,notification 能够针对one-to-one/many/none,reciever没法返回值给sender.因此,delegate用于sender但愿接受到 reciever的某个功能反馈值,notification用于通知多个object某个事件。
5> delegate和block
block使代码更紧凑,便于阅读,delegate能够设置必选和可选的方法实现,相比block
block能够访存局部变量. 不须要像之前的回调同样,把在操做后全部须要用到的数据封装成特定的数据结构, 你彻底能够直接访问局部变量.
3.KVC和KVO
1> 如何调用私有变量 如何修改系统的只读属性 KVC的查找顺序
KVC在某种程度上提供了访问器的替代方案。不过访问器方法是一个很好的东西,以致于只要是有可能,KVC也尽可能再访问器方法的帮助下工做。为了设置或者返回对象属性,KVC按顺序使用以下技术:
①检查是否存在-<key>、-is<key>(只针对布尔值有效)或者-get<key>的访问器方法,若是有可能,就是用这些方法返回值;
检查是否存在名为-set<key>:的方法,并使用它作设置值。对于 -get<key>和 -set<key>:方法,将大写Key字符串的第一个字母,并与Cocoa的方法命名保持一致;
②若是上述方法不可用,则检查名为-_<key>、-_is<key>(只针对布尔值有效)、-_get<key>和-_set<key>:方法;
③若是没有找到访问器方法,能够尝试直接访问实例变量。实例变量能够是名为:<key>或_<key>;
④若是仍为找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,咱们能够根据须要重写它们。
2> 什么是键-值,键路径是什么
模型的性质是经过一个简单的键(一般是个字符串)来指定的。视图和控制器经过键来查找相应的属性值。在一个给定的实体中,同一个属性的全部值具备相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。
键路径是一个由用点做分隔符的键组成的字符串,用于指定一个链接在一块儿的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每一个键的值也是相对于其前面的性质。键路径使您能够以独立于模型实现的方式指定相关对象的性质。经过键路径,您能够指定对象图中的一
个任意深度的路径,使其指向相关对象的特定属性。
3> 什么是KVC和KVO
KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所须要的环境参数。(2)他会从本身isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。KVO(Key-Value- Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。因此 isa指针其实不须要指向实例对象真实的类。因此咱们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名
4> kvo的实现机制
当某个类的对象第一次被观察时,系统就会在运行时动态地建立该类的一个派生类,在这个派生类中重写原类中被观察属性的setter方法,派生类在被重写的setter方法实现真正的通知机制(Person->NSKVONotifying_Person).
派生类重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。而后系统将这个对象的isa指针指向这个新诞生的派生类,所以这个对象就成为该派生类的对象了,于是在该对象上对setter的调用就会调用重写的setter,从而激活键值通知机制。此外,派生类还重写了dealloc方法来释放资源。
5> kvo使用场景
①实现上下拉刷新控件 contentoffset
②webview混合排版 contentsize
③监听模型属性实时更新UI
UI
一.控件
1.属性
1> frame和bounds的区别
frame:可表示尺寸和位置,与父视图坐标系的关系,位置以本身的左上角为原点,可用于形变和位移
bounds:可表示尺寸和位置,与自身视图坐标系的关系,大多数状况(滚动视图的子视图等除外)以本身的中心点为原点,可用于形变
center:只表示位置,表示本身中心的坐标,可用于位移
2> trasform
修改位移\形变\旋转,transform不一样于board\center\frame,前者中记录的是形变的数据,不发生形变其值是空的,因此咱们须要新建结构体,用CGAffineTransform(仿射变换)函数给对象结构体属性赋值,然后者是控件的固有属性,内存数据是始终存在的,当咱们用他们作移动等操做时,是改变其值,因此是结构体赋值三步曲,不用CG的函数
使用情景区别: transform通常用于有来有回的变化,而frame是有去无回
2.UITableview
1> 自定义高度
1.1>新建一个继承自UITableViewCell的类
1.2>重写initWithStyle:reuseIdentifier:方法
1.3>添加全部须要显示的子控件(不须要设置子控件的数据和frame, 子控件要添加到contentView中)
1.4>进行子控件一次性的属性设置(有些属性只须要设置一次, 好比字体\固定的图片)
1.5>提供2个模型
数据模型: 存放文字数据\图片数据
frame模型: 存放数据模型\全部子控件的frame\cell的高度
1.6>cell拥有一个frame模型(不要直接拥有数据模型)
1.7>重写frame模型属性的setter方法: 在这个方法中设置子控件的显示数据和frame
3.UICollectionView
1> 如何实现瀑布流,流水布局
经过实现UICollectionViewDelegateFlowLayout去改变单元格大小
2> 和UITableView的使用区别
1)必须使用下面的方法进行Cell类的注册:
2)collectionView与tableView最大的不一样点,collectionView必需要使用本身的layout(UICollectionViewLayout)
如:
建立collectionView须要带Layout的初始化方法:
二.生命周期
1> 应用的生命周期
各个程序运行状态时代理的回调:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告诉代理进程启动但还没进入状态保存
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告诉代理启动基本完成程序准备开始运行
- (void)applicationWillResignActive:(UIApplication *)application 当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,好比来电话了
- (void)applicationDidBecomeActive:(UIApplication *)application 当应用程序入活动状态执行,这个恰好跟上面那个方法相反
- (void)applicationDidEnterBackground:(UIApplication *)application 当程序被推送到后台的时候调用。因此要设置后台继续运行,则在这个函数里面设置便可
- (void)applicationWillEnterForeground:(UIApplication *)application 当程序从后台将要从新回到前台时候调用,这个恰好跟上面的那个方法相反。
- (void)applicationWillTerminate:(UIApplication *)application 当程序将要退出是被调用,一般是用来保存数据和一些退出前的清理工做。
2> 视图的生命周期
loadView - 默认调用super方法,根据控制器建立方式加载视图,重写后将根据重写方法建立视图
viewDidLoad-视图加载完成
viewWillAppear-UIViewController对象的视图即将加入窗口时调用;
viewDidApper-UIViewController对象的视图已经加入到窗口时调用;
viewWillDisappear-UIViewController对象的视图即将消失、被覆盖或是隐藏时调用;
viewDidDisappear-UIViewController对象的视图已经消失、被覆盖或是隐藏时调用;
viewVillUnload-当内存太低时,须要释放一些不须要使用的视图时,即将释放时调用;
viewDidUnload-当内存太低,释放一些不须要的视图时调用。
四.核心绘图
6> View和layer的区别
图层不会直接渲染到屏幕上,UIView是iOS系统中界面元素的基础,全部的界面元素都是继承自它。它自己彻底是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView自己更像是一个CALayer的管理器。一个UIView上能够有n个CALayer,每一个layer显示一种东西,加强UIView的展示能力。
6.1>均可以显示屏幕效果
6.2> 若是须要用户交互就要用UIVIew,其可接收触摸事件(继承UIResponder),而CALayer不能接收触摸事件
6.3> 若是没有用户交互可选用CALayer,由于其所在库较小,占用的资源较少
7> new和alloc init的区别
采用new的方式只能采用默认的init方法完成初始化,采用alloc的方式能够用其余定制的初始化方法。
六.事件处理
1> 描述响应者链条
当触摸事件发生时,压力转为电信号,iOS系统将产生UIEvent对象,记录事件产生的时间和类型,而后系统将事件加入到一个由UIApplication管理的事件队列中。
UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,一般,先发送事件给应用程序的主窗口(keyWindow)
主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件(从父到子,从后到前),这也是整个事件处理过程的第一步
找到合适的视图控件后,就会调用视图控件的touches方法来做具体的事件处理
4.Runloop
1> 每一个线程上都有一个runloop,主线程默认开启,辅助线程须要手动开启,主要用于
七.屏幕适配
多线程
一.资源抢夺
2> 资源抢夺解决方案
@sychronized{ }
dispatch_barrier_async
NSLock NSCondition
dispatch_semaphore_wait
二.iOS多线程技术
3> 对比iOS中的多线程技术
3.1> pthread
pthread跨平台,使用难度大,须要手动管理线程生命周期
pthread_create建立线程,传参线程标记,线程属性,初始函数,函数参数
3.2> NSThread
NSThread须要手动管理线程生命周期和
3.3> GCD
3.4> NSOperation
GCD是纯C语言的API,NSOperationQueue是基于GCD的OC版本封装
3.2> GCD仅仅支持FIFO队列,只能够设置队列的优先级,而NSOperationQueue中的每个任务均可以被从新设置优先级(setQueuePriority:),从而实现不一样操做的执行顺序调整
3.3> GCD不支持异步操做之间的依赖关系设置。若是某个操做的依赖另外一个操做的数据,使用NSOperationQueue可以设置依赖按照正确的顺序执行操做(addDependency:)。GCD则没有内建的依赖关系支持(只能经过Barrior和同步任务手动实现)。
3.4> NSOperationQueue方便中止队列中的任务(cancelAllOperations, suspended),GCD不方便中止队列中的任务.
3.5> NSOperationQueue支持KVO,能够监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)
3.6> GCD的执行速度比NSOperationQueue快
3.7> NSOperationQueue可设置最大并发数量(节电),GCD具备dispatch_once(只执行一次,单例)和dispatch_after(延迟执行)功能
3.8> NSObject分类(perform)和NSThread遇到对象分配须要手动内存管理,手动管理线程生命周期
3.9> NSThread查看线程
3.10> NSObject分类线程通讯
4> 原子属性
原子属性采用的是"多读单写"机制的多线程策略
"多读单写"缩小了锁范围,比互斥锁的性能好
规定只在主线程更新UI,就是由于若是在多线程中更新,就须要给UI对象加锁,防止资源抢占写入错误,可是这样会下降UI交互的性能,因此ios设计让全部UI对象都是非线程安全的(不加锁),并规定只在主线程中更新UI,规避多线程抢占资源问题
三.其余
5> 多线程优缺点
优势:
使应用程序的响应速度更快,用户界面在进行其余工做的同时仍始终保持活动状态;
优化任务执行,适当提升资源利用率(cpu, 内存);
缺点:
线程占用内存空间,管理线程须要额外的CPU开销,开启大量线程,下降程序性能;
增长程序复杂度,如线程间通讯,多线程的资源共享等;
1> 在多线程中使用通知须要注意什么问题?
网络
一.网络基础
1.数据解析
1> XML解析方式
SAX 方式解析
-只读
-速度快
-从上向下
-经过5个代理方法解析,每一个代理方中都须要写一些代码!
-若是要实现SAX解析,思路最重要!
-适合比价大的XML的解析
DOM解析的特色
-一次性将XML所有加载到内存,以树形结构
-好处,能够动态的修改,添加,删除节点
-内存消耗很是大!尤为横向节点越深!
-iOS默认不支持 DOM 解析!
-在 MAC 端,或者服务器端开发,都基本上使用 DOM 解析
-在 iOS 端若是须要使用 DOM 方式解析,可使用第三方框GData/KissXML(XMPP)
-适合比较小的 XML 文件
-在 MAC 中,苹果提供了一个 NSXML 的类,可以作 DOM 解析,在 iOS 不能使用!
2.网络协议
1>TCP如何防止乱序和丢包
TCP数据包的头格式中有两个概念,Sequence Number是数据包的序号,用来解决网络包乱序(reordering)问题。Acknowledgement Number就是ACK——用于确认收到,用来解决不丢包的问题。
位码即tcp标志位,有6种标示:SYN(synchronous创建联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)Sequence number(顺序号码) Acknowledge number(确认号码).
SeqNum的增长是和传输的字节数相关的,TCP传输数据时,A主机第一次传输1440个字节,seq=1,那么第二次时seq = 1441,B拼接数据就是根据seq进行拼接的,seq数字不断累加避免了乱序.B主机收到第一次数据包之后会返回ack = 1441.
A主机收到B的ack = 1441时,就知道第一个数据包B已收到. 若是B没有收到第一次的数据包,那么B再收到A的数据包时,他就会发ack = 1回去,A收到B的回复,发现B没有收到第一次数据包,就会重发第一次数据包,这样就能够防止丢包.
2>描述一下三次握手
第一次握手:创建链接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时本身也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据.
3> TCP与UDP的区别:
3.1>基于链接与无链接;
3.2>对系统资源的要求(TCP较多,UDP少);
3.3>UDP程序结构较简单;
3.4>流模式与数据报模式 ;
3.5>TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
4>http和scoket通讯的区别
http是客户端用http协议进行请求,发送请求时候须要封装http请求头,并绑定请求的数据,服务器通常有web服务器配合(固然也非绝对)。 http请求方式为客户端主动发起请求,服务器才能给响应,一次请求完毕后则断开链接,以节省资源。服务器不能主动给客户端响应(除非采起http长链接技术)。iPhone主要使用类是NSUrlConnection。
scoket是客户端跟服务器直接使用socket“套接字”进行链接,并无规定链接后断开,因此客户端和服务器能够保持链接通道,双方均可以主动发送数据。通常在游戏开发或股票开发这种要求即时性很强而且保持发送数据量比较大的场合使用。主要使用类是CFSocketRef。
3.网络传输
1>DNS是如何工做的
DNS是domain name server的简称,每一个网络的计算机都有ip,可是很差记,因此用域名替代(如www.baidu.com),在 Internet 上真实在辨识机器的仍是 IP,因此当使用者输入Domain Name 后,浏览器必需要先去一台有 Domain Name 和IP 对应资料的主机去查询这台电脑的 IP,而这台被查询的主机,咱们称它为 Domain Name Server,简称DNS,例如:当你输入www.pchome.com.tw时,浏览器会将www.pchome.com.tw这个名字传送到离他最近的 DNS Server 去作辨识,若是查到,则会传回这台主机的 IP,进而跟它索取资料,但若是没查到,就会发生相似 DNS NOT FOUND 的情形,因此一旦DNS Server当机,就像是路标彻底被毁坏,没有人知道该把资料送到那里
二.网络安全/加密
料送到那里
三.数据存储
1.数据存储技术
1> 数据存储的几种方式
1.1> plist xml
1.2> 偏好设置
1.3> 归档 Document 自定义对象 NSCoding协议
如何使用plist保存视图尺寸 NSValue
2> 沙盒目录结构
2.1> Library Caches Preferences
2.2> Documents
2.3> tmp
2.数据库技术(SQLite&CoreData)
四.Html5/oc&js互调
oc>js:[self.webView stringByEvaluatingJavaScriptFromString:“window.location.href = xxx”];
js>oc: 利用hmtl中js的重定向技术,<Script> window.location.href = www.baidu.com//method:dosomething </Script>
使用方法截取重定向
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
五.iOS网络框架
1> NSURLConnection和NSURLSession的区别
1.1> 异步请求不须要NSOperation包装
1.2> 支持后台运行的网络任务(后台上传下载)
1.3> 根据每一个Session作配置(http header,Cache,Cookie,protocal,Credential),再也不在整个App层面共享配置
1.4> 支持网络操做的取消和断点续传(继承系统类,从新main方法)
1.5> 改进了受权机制的处理
项目
1.实用技术
2.知名第三方框架
3.开发技巧
1> description方法
Swift
1> Swift和OC的区别
1.1> Swift没有地址/指针的概念
1.2> 泛型
1.3> 类型严谨 对比oc的动态绑定
6.设计模式
1> 经常使用的设计模式
代理 观察者 工厂 单例 策略
2> 代理属性的内存策略是什么,为何?
3> 观察者模式的使用场景
4> 工厂模式(类方法)为何没有释放对象? autorelease工做原理? arc下还须要手动使用autorelease吗?为何?什么场景?
5> 手写单例
6> 策略 cell多种响应效果 代理方法
(一)代理模式
应用场景:当一个类的某些功能须要由别的类来实现,可是又不肯定具体会是哪一个类实现。
优点:解耦合
敏捷原则:开放-封闭原则
实例:tableview的 数据源delegate,经过和protocol的配合,完成委托诉求。
列表row个数delegate
自定义的delegate
(二)观察者模式
应用场景:通常为model层对controller和view进行的通知方式,不关心谁去接收,只负责发布信息。
优点:解耦合
敏捷原则:接口隔离原则,开放-封闭原则
实例:Notification通知中心,注册通知中心,任何位置能够发送消息,注册观察者的对象能够接收。
kvo,键值对改变通知的观察者,平时基本没用过。
(三)MVC模式
应用场景:是一中很是古老的设计模式,经过数据模型,控制器逻辑,视图展现将应用程序进行逻辑划分。
优点:使系统,层次清晰,职责分明,易于维护
敏捷原则:对扩展开放-对修改封闭
实例:model-即数据模型,view-视图展现,controller进行UI展示和数据交互的逻辑控制。
(四)单例模式
应用场景:确保程序运行期某个类,只有一份实例,用于进行资源共享控制。
优点:使用简单,延时求值,易于跨模块
敏捷原则:单一职责原则
实例:[UIApplication sharedApplication]。
注意事项:确保使用者只能经过 getInstance方法才能得到,单例类的惟一实例。
java,C++中使其没有公有构造函数,私有化并覆盖其构造函数。
object c中,重写allocWithZone方法,保证即便用户用 alloc方法直接建立单例类的实例,返回的也只是此单例类的惟一静态变量。
(五)策略模式
应用场景:定义算法族,封装起来,使他们之间能够相互替换。
优点:使算法的变化独立于使用算法的用户
敏捷原则:接口隔离原则;多用组合,少用继承;针对接口编程,而非实现。
实例:排序算法,NSArray的sortedArrayUsingSelector;经典的鸭子会叫,会飞案例。
注意事项:1,剥离类中易于变化的行为,经过组合的方式嵌入抽象基类
2,变化的行为抽象基类为,全部可变变化的父类
3,用户类的最终实例,经过注入行为实例的方式,设定易变行为
防止了继承行为方式,致使无关行为污染子类。完成了策略封装和可替换性。
(六)工厂模式
应用场景:工厂方式建立类的实例,多与proxy模式配合,建立可替换代理类。
优点:易于替换,面向抽象编程,application只与抽象工厂和易变类的共性抽象类发生调用关系。
敏捷原则:DIP依赖倒置原则
实例:项目部署环境中依赖多个不一样类型的数据库时,须要使用工厂配合proxy完成易用性替换
注意事项:项目初期,软件结构和需求都没有稳定下来时,不建议使用此模式,由于其劣势也很明显,
增 加了代码的复杂度,增长了调用层次,增长了内存负担。因此要注意防止模式的滥用。
六.框架
1.SDWebimage
1> SDWebimage的缓存机制
位运算
NSCache
特色: a> 线程安全的 b> 当内存不足的时候,自动释放 c> 缓存数量和缓存成本
区别NSMutableDictionary
1> 不能也不该该遍历 2> NSCache对key强引用,NSMutableDictionary对key进行copy
2.AFN
1>实现原理
AFN的直接操做对象AFHTTPClient不一样于ASI,是一个实现了NSCoding和NSCopying协议的NSObject子类。 AFHTTPClient是一个封装了一系列操做方法的“工具类”,处理请求的操做类是一系列单独的,基于NSOperation封装 的,AFURLConnectionOperation的子类。AFN的示例代码中经过一个静态方法,使用dispatch_once()的方式建立 AFHTTPClient的共享实例,这也是官方建议的使用方法。在建立AFHTTPClient的初始化方法中,建立了OperationQueue并 设置一系列参数默认值。在getPath:parameters:success:failure方法中建立NSURLRequest,以 NSURLRequest对象实例做为参数,建立一个NSOperation,并加入在初始化发方中建立的NSOperationQueue。以上操做都 是在主线程中完成的。在NSOperation的start方法中,以此前建立的NSURLRequest对象为参数建立NSURLConnection 并开启连结。
2> 传递指针 如何使一个方法返回多个返回值
七.项目
3.混编
arc mrc混编
c c++混编
4.加密
八.算法
交换数值的几种方法 中间变量 加减法 异或
二叉树
链表
递归