A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 柳柳桑 黑马粉丝团   /  2016-3-7 14:23  /  18477 人查看  /  294 人回复  /   12 人收藏 转载请遵从CC协议 禁止商业使用本文


iOS面试之内存管理篇

内存管理(★★★)

  一、怎么保证多人开发进行内存泄露的检查。


  • 使用Analyze进行代码的静态分析

  • 为避免不必要的麻烦, 多人开发时尽量使用ARC


  二、非自动内存管理情况下怎么做单例模式。


  创建单例设计模式的基本步骤:

  >声明一个单件对象的静态实例,并初始化为nil;

  >创建一个类的类工厂方法,当且仅当这个类的实例为nil时生成一个该类的实例;

  >实现NScopying协议, 覆盖allocWithZone:方法,确保用户在直接分配和初始化对象时,不会产 生另一个对象;

  >覆盖release、autorelease、retain、retainCount方法, 以此确保单例的状态;

  >在多线程的环境中,注意使用@synchronized关键字或GCD,确保静态实例被正确的创建和初始化。


  三、对于类方法(静态方法)默认是autorelease的。所有类方法都会这样吗?


  1> 系统自带的绝大数类方法返回的对象,都是经过autorelease的。


  四、block在ARC中和MRC中的用法有什么区别,需要注意什么?


  1.对于没有引用外部变量的Block,无论在ARC还是非ARC下,类型都是__NSGlobalBlock__,这种类型的block可以理解成一种全局的block,不需要考虑作用域问题。同时,对他进行Copy或者Retain操作也是无效的;

  2.应注意避免循环引用。


  五、什么情况下会发生内存泄漏和内存溢出?


  当程序在申请内存后,无法释放已申请的内存空间(例如一个对象或者变量使用完成后没有释放,这个对象一直占用着内存),一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。内存泄露会最终会导致内存溢出!

  当程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个int,但给它存了long才能存下的数,那就是内存溢出。


  六、[NSArrayarrayWithobject:] 这个方法添加对象后,需要对这个数组做释放操作吗?

  不需要 这个对象被放到自动释放池中。


  七、Json数据的解析?


  • JSON解析的方案


  1、SBJson
;

  2、JSONkit
;

  3、NSJSONSerialization
。


  八、自动释放池底层怎么实现?


  自动释放池以栈的形式实现:当你创建一个新的自动释放池时,它将被添加到栈顶。当一个对象收到发送autorelease消息时,它被添加到当前线程的处于栈顶的自动释放池中,当自动释放池被回收时,它们从栈中被删除, 并且会给池子里面所有的对象都会做一次release操作。


  九、自动释放池是什么,如何工作?


  当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

  1. ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁。

  2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的。

  3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一。


  十、Objective-C如何对内存管理的,说说你的看法和解决方法?


  Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。

  1、(Garbage Collection)自动内存计数:这种方式和java类似,在你的程序的执行过程中。始终有一个高人在背后准确地帮你收拾垃圾,你不用考虑它什么时候开始工作,怎样工作。你只需要明白,我申请了一段内存空间,当我不再使用从而这段内存成为垃圾的时候,我就彻底的把它忘记掉,反正那个高人会帮我收拾垃圾。遗憾的是,那个高人需要消耗一定的资源,在携带设备里面,资源是紧俏商品所以iPhone不支持这个功能。所以“Garbage Collection”不是本入门指南的范围,对“GarbageCollection”内部机制感兴趣的同学可以参考一些其他的资料,不过说老实话 “GarbageCollection”不大适合适初学者研究。

  解决:通过alloc– initial方式创建的, 创建后引用计数+1, 此后每retain一次引用计数+1,那么在程序中做相应次数的release就好了。

  2、(Reference Counted)手动内存计数:就是说,从一段内存被申请之后,就存在一个变量用于保存这段内存被使用的次数,我们暂时把它称为计数器,当计数器变为0的时候,那么就是释放这段内存的时候。比如说,当在程序A里面一段内存被成功申请完成之后,那么这个计数器就从0变成1(我们把这个过程叫做alloc),然后程序B也需要使用这个内存,那么计数器就从1变成了2(我们把这个过程叫做retain)。紧接着程序A不再需要这段内存了,那么程序A就把这个计数器减1(我们把这个过程叫做release);程序B也不再需要这段内存的时候,那么也把计数器减1(这个过程还是release)。当系统(也就是 Foundation)发现这个计数器变成了0,那么就会调用内存回收程序把这段内存回收(我们把这个过程叫做dealloc)。顺便提一句,如果没有 Foundation,那么维护计数器,释放内存等等工作需要你手工来完成。

  解决:一般是由类的静态方法创建的, 函数名中不会出现alloc或init字样, 如[NSStringstring]和[NSArray arrayWithObject:], 创建后引用计数+0,在函数出栈后释放, 即相当于一个栈上的局部变量. 当然也可以通过retain延长对象的生存期。

  3、(NSAutoRealeasePool)内存池:可以通过创建和释放内存池控制内存申请和回收的时机。

  解决:是由autorelease加入系统内存池,内存池是可以嵌套的, 每个内存池都需要有一个创建释放对, 就像main函数中写的一样. 使用也很简单,比如[[[NSString alloc]initialWithFormat”Hey you!”] autorelease], 即将一个NSString对象加入到最内层的系统内存池, 当我们释放这个内存池时, 其中的对象都会被释放。


  十一、需要在手动管理内存分配和释放的Xcode项目中引入和编译用ARC风格编写的文件,需要在文件的CompilerFlags上添加参数。


294 个回复

正序浏览
过来学习~~~~~
回复 使用道具 举报
有一部分还是似懂非懂
回复 使用道具 举报
学习技术,加强技能
回复 使用道具 举报
哇哇哇哇哇哇哇哇哇哇哇
回复 使用道具 举报
赞一个,说的太详细了
回复 使用道具 举报
来参观学习!
回复 使用道具 举报
点赞,路过留名,顺便寻找我魂牵梦绕的黑马币。
回复 使用道具 举报
收一个先
回复 使用道具 举报
很实用的教程
回复 使用道具 举报
赞赞赞!!!1
回复 使用道具 举报
itlf 中级黑马 2016-5-20 22:58:48
284#
好!!!!!!!!!!!
回复 使用道具 举报
新手   表示看不懂   但是很屌
回复 使用道具 举报
还不懂 先收藏个
回复 使用道具 举报
非常好的东东,学习了
回复 使用道具 举报
非常好的东东
回复 使用道具 举报
我要好好看看
回复 使用道具 举报
顶一个 虽然看不懂
回复 使用道具 举报
TGII 中级黑马 2016-5-20 00:18:00
277#
还没学到,不过已经收藏
回复 使用道具 举报
好厉害好厉害好厉害
回复 使用道具 举报
好贴 学习了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马