13.谈下Objective C都有哪些锁机制,你一般用哪个?
1)NSLock
iOS中对于资源抢占的问题可以使用同步锁NSLock来解决,使用时把需要加锁的代码(以后暂时称这段代码为”加锁代码“)放到NSLock的lock和unlock之间,一个线程A进入加锁代码之后由于已经加锁,另一个线程B就无法访问,只有等待前一个线程A执行完加锁代码后解锁,B线程才能访问加锁代码。
2)@synchronized代码块
使用@synchronized解决线程同步问题相比较NSLock要简单一些,日常开发中也更推荐使用此方法。
3)使用GCD解决资源抢占问题
在GCD中提供了一种信号机制,也可以解决资源抢占问题(和同步锁的机制并不一样)。
4)扩展--控制线程通信
由于线程的调度是透明的,程序有时候很难对它进行有效的控制,为了解决这个问题iOS提供了NSCondition来控制线程通信(同前面GCD的信号机制类似)。
5)iOS中的其他锁
NSRecursiveLock :递归锁,有时候“加锁代码”中存在递归调用,递归开始前加锁,递归调用开始后会重复执行此方法以至于反复执行加锁代码最终造成死锁,这个时候可以使用递归锁来解决。使用递归锁可以在一个线程中反复获取锁而不造成死锁,这个过程中会记录获取锁和释放锁的次数,只有最后两者平衡锁才被最终释放。
NSDistributedLock:分布锁,它本身是一个互斥锁,基于文件方式实现锁机制,可以跨进程访问。
pthread_mutex_t:同步锁,基于C语言的同步锁机制,使用方法与其他同步锁机制类似。
URL:http://blog.csdn.net/roger_jin/article/details/45307951
14.聊下HTTP post的body体使用form-urlencoded和multipart/form-data的区别。
1)application/x-www-form-urlencoded: 窗体数据被编码为名称/值对,这是标准且默认的编码格式。当action为get时候,客户端把form数据转换成一个字串append到url后面,用?分割。当action为post时候,浏览器把form数据封装到http body中,然后发送到server。
2)multipart/form-data: multipart表示的意思是单个消息头包含多个消息体的解决方案。multipart媒体类型对发送非文本的各媒体类型是有用的。一般多用于文件上传。 multipart/form-data只是multipart的一种。目前常用的有以下这些类型(注:任何一种执行时无法识别的multipart子类型都被视为子类型"mixed") URL:
http://blog.csdn.net/soonfly/article/details/52082547
15.让你设计一种机制检测UIViewController的内存泄漏,你会怎么做?
如果Controller被释放了,但其曾经持有过的子对象如果还存在,那么这些子对象就是泄漏的可疑目标。
一个小示例:子对象(比如view)建立一个对controller的weak引用,如果Controller被释放,这个weak引用也随之置为nil。那怎么知道子对象没有被释放呢?用一个单例对象每个一小段时间发出一个ping通知去ping这个子对象,如果子对象还活着就会一个pong通知。所以结论就是:如果子对象的controller已不存在,但还能响应这个ping通知,那么这个对象就是可疑的泄漏对象。
URL:http://blog.sina.com.cn/s/blog_7e6a4f740102wce9.html
16.通过[UIImage imageNamed:]生成的对象什么时候被释放?
使用imageNamed这个方法生成的UIImage对象,会在应用的bundle中寻找图片,如果找到则Cache到系统缓存中,作为内存的cache,而程序员是无法操作cache的,只能由系统自动处理,如果我们需要重复加载一张图片,那这无疑是一种很好的方式,因为系统能很快的从内存的cache找到这张图片,但是试想,如果加载很多很大的图片的时候,内存消耗过大的时候,就会会强制释放内存,即会遇到内存警告(memory warnings).
由于在iOS系统中释放图片的内存比较麻烦,所以冲易产生内存泄露。 像[[UIImageView alloc] init]还有一些其他的 init 方法,返回的都是 autorelease 对象。而 autorelease 不能保证什么时候释放,所以不一定在引用计数为 0 就立即释放,只能保证在 autoreleasepool 结尾的时候释放。
像 UIImage 还有 NSData 这种,大部分情况应该是延迟释放的,可以理解为到 autoreleasepool 结束的时候才释放。
URL:https://segmentfault.com/q/1010000004230892、http://blog.csdn.net/qq_18505715/article/details/72885498
17.applicationWillEnterForeground和applicationDidBecomeActive都会在哪些场景下被调用?举例越多越好。
1)applicationWillResignActive(将进入后台)
对应applicationWillEnterForeground(将进入前台)
程序将要失去Active状态时调用,比如按下Home键或有电话信息进来,这个方法用来
- 暂停正在执行的任务;
- 禁止计时器;
- 减少OpenGL ES帧率;
- 若为游戏应暂停游戏;
总结为一个字:停!
2)applicationDidEnterBackground(已经进入后台)
对应applicationDidBecomeActive(已经变成前台)
程序已经进入后台时调用,这个方法用来
- 释放共享资源;
- 保存用户数据(写到硬盘);
- 作废计时器;
- 保存足够的程序状态以便下次恢复; 总结为4个字:释放、保存!
URL:https://www.cnblogs.com/chenyg32/p/3873301.html
18.如何终止正在运行的工作线程?
iOS 8 以后,通过dispatch_block_cancel可以cancel掉dispatch_block_t,需要注意的是,未执行的可以用此方法cancel掉,若已经执行则cancel不掉;
如果想中断(interrupt)线程,可以使用dispatch_block_testcancel方法;值得注意的是,swift3之后DispatchWorkItem代替了dispatch_block_t,有很方便的cancel()和isCancelled可以使用。
1)使用退出标志终止线程 当run方法执行完后,线程就会退出,...return.
2)使用stop方法终止线程 thread.stop();
使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果
3)使用interrupt方法终止线程 1>线程处于阻塞状态,如使用了sleep方法,将抛出一个InterruptedException例外。 2>使用while(!isInterrupted()){……}来判断线程是否被中断,线程将直接退出。
URL:http://blog.csdn.net/zhanjichun_2008/article/details/6612980、https://www.zhihu.com/question/23919984
19.穷举iOS下所有的本地持久化方案。
- plist文件(属性列表)
- preference(偏好设置)
- NSKeyedArchiver(归档)
- SQLite 3
- CoreData URL:http://www.cocoachina.com/ios/20150720/12610.html
自己网上整理,有不对的地方还请大佬们指点~