iOS: 总结

PS:内存处理、缓存处理、性能优化、断点续传-AFN、如何解决内存飙升 & 解析效率?

 

1、关于SVN冲突

解决冲突有三种选择:

A、放弃自己的更新,使用svn revert(回滚),然后提交。在这种方式下不需要使用svn resolved(解决)

B、放弃自己的更新,使用别人的更新。使用最新获取的版本覆盖目标文件,执行resolved filename并提交(选择文件—右键—解决)。

C、手动解决:冲突发生时,通过和其他用户沟通之后,手动更新目标文件。然后执行resolved filename来解除冲突,最后提交。

如何降低冲突解决的复杂度:

1、当文档编辑完成后,尽快提交,频繁的提交/更新可以降低在冲突发生的概率,以及发生时解决冲突的复杂度。

2、在提交时,写上明确的message,方便以后查找用户更新的原因,毕竟随着时间的推移,对当初更新的原因有可能会遗忘

3、养成良好的使用习惯,使用SVN时每次都是先提交,后更新。每天早上打开后,首先要从版本库获取最新版本。每天下班前必须将已经编辑过的文档都提交到版本库。

 

2、json解析,xml解析,plist解析

 

json解析:自带的反序列化解析(轻量级,慢慢取代xml)  NSJSONSerialization--专门将 JSON 转换成 Foundation 对象和将 Foundation 对象转换成 JSON 的类

XML--指可扩展标记语言(eXtensible Markup Language):

1、SAX解析:1.打开文档、2.开始节点、3.发现节点内容、4.结束节点、5.结束文档   --苹果使用 XMLParser 实现

2、DOM解析:1.一次性将XML文档以树型结构读入内存 2.iOS默认不支持 DOM 方式解析 3.使用 DOM 解析,适合非常小的XML数据结构

plist解析:

[NSPropertyListSerialization propertyListWithData:data options:0 format:NULL error:NULL];

NSPropertyListReadOptions

 

PS:

序列化:向服务器发送请求前,需要把提交给服务器的 OC 对象转换成二进制数据

反序列化:从服务器接收到数据后,需要将服务器返回的二进制数据转换成 OC 对象

归档 & 解档:

- (void)encodeWithCoder:(NSCoder *)encoder

  使用编码器将对象编码成二进制数据流,归档(持久化存储)

- (instancetype)initWithCoder:(NSCoder *)decoder

  使用解码器,将保存在磁盘上的二进制数据流,解码成OC对象

 

3、AFN与ASI对比

-AFN
1. 基于 NSURLConnection & NSURLSession 进行的封装
2. 使用简单
3. 提供了自动的序列化 & 反序列化支持!

AFN的优势:
URL直接传字符串
响应回来得到的数据可以半自动反序列化(json可以自动(afn默认json解析),xml需要手动)
代码回调在主线程,不需要关心线程间通讯
用字典传递参数(parameters),不用写在URL里(GET),或请求体里(POST)
根据api文档,修改GET请求和POST请求,不需要关注如何选择

1、断点续传:1. 获取网络文件信息、2. 检查本地文件信息、3. 根据偏移位置下载文件

  NSString *range = [NSString stringWithFormat:@"bytes=%llu-", self.currentLength];

  [request setValue:range forHTTPHeaderField:@"Range"];

2、多线程分析

3、分段保存(解决内存峰值突增):

  NSFileManager:做文件的复制,删除,检查是否存在,创建目录,删除目录,遍历目录...类似于在Finder中的操作

  NSFileHandle:针对一个文件做二进制数据的读写操作

技巧:可以利用 MD5 检测文件下载是否正确 !

  以文件流的方式写入数据:NSStream也是Socket开发中非常重要的一个环节

技巧:创建一个单例,统一管理全局所有的网络会话


-ASI
1. 基于 CFNetwork 进行的封装 Core Foundation,是底层的 C 语言的框架,ASI 的效率是跟好的
2. 使用非常灵活,给程序员提供了各种使用的可能和空间!
* 用代理
* 用块代码
* 自定义监听方法
* 自定义代理-> 开发者可以定制专属自己的网络管理工具!

3. 使用难度大
4. MRC的,需要考虑到 ARC & MRC 混编的问题
5. 返回内容只是提供了二进制数据,或者字符串(前提结果确实是字符串!)
ASI的序列化和反序列化需要程序员自己来!

// ASI通过代理的方式处理异步请求,请求成功、失败都会通知代理

//  代理需要遵守ASIHTTPRequestDelegate协议

PS:通过block回调传值、发送POST请求、文件上传&下载、ASI数据缓存、缓存某个请求 等。

  • 实际上ASIHTTPRequest继承自NSOperation,意味着
  • 可以将多个ASIHTTPRequest放到NSOperationQueue中,同时管理多个请求
  • 可以设置请求之间的依赖 
  • ASIFormDataRequest继承自ASIHTTPRequest

其他用法:

1、现在是否有网络请求在处理中

[ASIHTTPRequest isNetworkInUse];

 

2、当正在请求时,是否要在状态栏显示联网状态(转圈圈)

[ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:YES];

 

3、当应用后台运行时,是否仍然继续处理网络请求

request.shouldContinueWhenAppEntersBackground = YES;

 

4、设置请求超时后重试的次数

request.numberOfTimesToRetryOnTimeout = 2; // 重试2

] 

 

4、内存管理:
内存管理需要和cpu的使用率综合考虑,保证合理的内存使用空间来提升程序的运行效率。
资源使用优先级: 系统内存缓存 -> 数据库缓存 -> 沙盒缓存 -> 网络加载

 

5、运行时特性:
OC中是发送消息(消息结构):运行时所执行的代码是由运行环境决定,函数调用的语言运行时执行的代码,是由编译器决定。OC重要的工作都由runtime component完成,runtime component本质是一种与开发者编写的代码相关连的dynamic library,这样以来,只要更新runtime component即能提升程序性能。

运行时机制:
1> runtime,运行时机制,它是一套C语言库

2> 实际上我们编写的所有OC代码,最终都是转成了runtime库的东西,比如类转成了runtime库里面的结构体等数据类型,方法转成了runtime库里面的C语言函数,平时调方法都是转成了objc_msgSend函数(所以说OC有个消息发送机制)

3> 因此,可以说runtime是OC的底层实现,是OC的幕后执行者 4> 有了runtime库,能做什么事情呢?runtime库里面包含了跟类、成员变量、方法相关的API,比如获取类里面的所有成员变量,为类动态添加成员变量,动态改变类的方法实现,为类动态添加新的方法等

[ 运行时获取对象属性之后需要释放

 

6、GCD和NSOperation的区别:
GCD原理:系统有个线程池,用于分配和回收线程,程序员不需要对线程管理
GCD的高级功能:延迟执行after,一次性执行once(单例),调度组(实现批量处理)
GCD存在四种组合,NSOperation只有全局队列、异步操作,如果想同步,必须用依赖关系
NSOperation的高级:最大并发数,控制线程个数,优化了线程的暂停、继续、取消功能(GCD实现起来太难),依赖关系,可以让异步任务同步执行

1. GCD是底层的C语言构成的API,而NSOperationQueue及相关对象是Objc的对象。在GCD中,在队列中执行的是由block构成的任务,这是一个轻量级的数据结构;而Operation作为一个对象,为我们提供了更多的选择;
2. 在NSOperationQueue中,我们可以随时取消已经设定要准备执行的任务(当然,已经开始的任务就无法阻止了),而GCD没法停止已经加入queue的block(其实是有的,但需要许多复杂的代码);
3. NSOperation能够方便地设置依赖关系,我们可以让一个Operation依赖于另一个Operation,这样的话尽管两个Operation处于同一个并行队列中,但前者会直到后者执行完毕后再执行;
4. 我们能将KVO应用在NSOperation中,可以监听一个Operation是否完成或取消,这样子能比GCD更加有效地掌控我们执行的后台任务;
5. 在NSOperation中,我们能够设置NSOperation的priority优先级,能够使同一个并行队列中的任务区分先后地执行,而在GCD中,我们只能区分不同任务队列的优先级,如果要区分block任务的优先级,也需要大量的复杂代码;
6. 我们能够对NSOperation进行继承,在这之上添加成员变量与成员方法,提高整个代码的复用度,这比简单地将block任务排入执行队列更有自由度,能够在其之上添加更多自定制的功能。
7. GCD 是严格的队列,先进先出 FIFO;NSOperation可以改动 优先级(或者说服务质量)改变执行顺序

NSOperation的高级:最大并发数,控制线程个数,优化了线程的暂停、继续、取消功能(GCD实现起来太难,可以用 KVO ),依赖关系,可以让异步任务同步执行

 

7、关于SDWebImage缓存

SDWebImage的缓存处理一定要深究,比较复杂,建议自己好好总结,看刀哥视频
SDImageCache类提供一个创建空缓存的实例,并用方法imageForKey:来寻找当前缓存。UIImage *myCachedImage = [[SDImageCache sharedImageCache] imageFromKey:myCacheKey]; 存储一个图像到缓存是使用方法storeImage: forKey: 默认情况下,图像将被存储在内存缓存和磁盘缓存中。如果仅仅是想内存缓存中,要使用storeImage:forKey:toDisk:方法的第三个参数带一负值来替代。

 

8、socket实现过程

socket是网络的底层,苹果原装的网络处理,afn,都是基于socket以上来封装的

NSStream也是Socket开发中非常重要的一个环节

 

9、本地推送和远程推送。

  本地通知和远程推送通知都可以向不在前台运行的应用发送消息,这种消息既可能是即将发生的事件,也可能是服务器的新数据.不管是本地通知还是远程通知,他们在程序界面的显示效果相同,都可能显示为一段警告信息或应用程序图标上的微章.

  本地通知和远程推送通知的基本目的都是让应用程序能够通知用户某些事情, 而且不需要应用程序在前台运行.二者的区别在于本地通知由本应用负责调用,只能从当前设备上的iOS发出, 而远程通知由远程服务器上的程序发送到APNS,再由APNS把消息推送至设备上的程序

 

10、比较

oc和c++比较:
  object_c比C++稍慢,是因为object_c的一些语言特性,比如反射,影响了执行效率。

区别主要有以下一些方面。单一继承:Objective-C不支持多重继承,(同Java和Smalltalk),而C++语言支持多重继承。

动态:Objective-C是动态定型(dynamicaly typed)所以它的类库比C++要容易操作。

Objective-C 在运行时可以允许根据字符串名字来访问方法和类,还可以动态连接和添加类。C++ 跟从面向对象编程里的Simula67(一种早期OO语言)学派,而Objecive-C属于Smalltalk学派。 在C++里,对象的静态类型决定你是否可以发送消息给它,而对Objecive-C来说,由动态类型来决定。

Simula 67学派更安全,因为大部分错误可以在编译时查出。而Smalltalk学派更灵活,比如一些Smalltalk看来无误的程序拿到Simualr 67那里就无法通过。从很多方面来看,C++和Objective-C的差别,与其说时技术上的,不如说是思维方式上的

[PS:我们通过协议来实现类似C++中的多继承,一个对象,一旦遵守了协议,就能够实现某个协议定义的方法!

 

android 与 ios 比较:

  • Android使用JAVA,上手容易很多,如果有很好的JAVA Lib加持,开发效率会高些
  • iOS没有虚拟机,性能要好一些,当然这个差别会随着Google的改进越来越小
  • iOS的开发框架基本上和MAC上通用,同样的知识,可以开发手机,也可以开发MAC应用,Android没有这样的优点
  • Android平台可以做的事情远远比iOS多, 你可以做电话管理,地址簿,短信管理,可以自己跑后台service。 替换掉系统的组件非常容易
  • Android平台也可以跑其他系统的Runtime, 比如Flash, 有了NDK, 你要自己接入一个虚拟机也是可能的。Google不会管你
  • 任何人可以拿Android自己改个独立的系统出来,也许这样做的意义和前景有问题,但是同样,没有人限制你

 

iOS ARC与MRC混编的一些解决方法:

1、ARC中使用到MRC第三方库:在编译选项中,为MRC的程序添加-fno-objc-arc标记,表明在编译时,该文件使用MRC编译

    (如果要在MRC项目中添加ARC的文件,可以使用 -fobjc-arc 标记即可)

["点击项目名"--Build Phases--Compile Sources--"双击文件"配置(Compiler Flags)--"添加-fno-objc-arc"]

 

2、将MRC的第三方库直接编译成静态库使用

  注意:在编译静态库时,不能添加动态库引用

       在项目中,如果使用的静态库中包含分类,则需要在Other Link Flag中添加 -ObjC选项

 

3、使用Xcode的转换工具--就没有成功过!!

 

---------

推荐博客

破船之家:http://beyondvincent.com/archives/

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。