iOS面试题02-内存管理(★★★)

《2018 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”不是本入门指南的范围,对“Garbage Collection”内部机制感兴趣的同学可以参考一些其他的资料,不过说老实话“Garbage Collection”不大适合适初学者研究。解决: 通过 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 字样, 如[NSString string]和[NSArray arrayWithObject:], 创建后引用计数+0, 在函数出栈后释放, 即相当于一个栈上的局部变量.当然也可以通过retain延长对象的生 期.3.(NSAutoRealeasePool)内存池:可以通过创建和释放内存池控制内存申请和回收的时机.解决:是由 autorelease 加入系统内存池, 内存池是可以嵌套的, 每个内存池都需要有一个创建释放对, 就像 main 函数中写的一样. 使用也很简单, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即将一个NSString 对象加入到最内层的系统内存池, 当我们释放这个内存池时, 其中的对象都会被释放.


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

-fobjc-arc
提示:
打开:-fobjc-arc
关闭:-fno-objc-arc

你可能感兴趣的:(iOS面试题02-内存管理(★★★))