由于近期要准备面试,所以把知识点总结下
1.ARC与MRC的区别
MRC是引用计数机制用来管理内存。当oc对象发生一次alloc/retain/copy的时候,retainCount+1。当oc对象发生一次release的时候,retainCount-1。若retainCount=0时,销毁该对象。
而autorelease是将对象交给自动释放池,当自动释放池销毁时会给其中的对象都发送一次release消息。
自动释放池的创建有以下两种
- @autoreleasepool { }
-
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; [pool release];
ARC是在编译过程中,自动给对象发送retain/release等消息大大减少了内存管理的麻烦。只要一个对象有强指针指向,这个对象就不会被释放
MRC的缺点:
- 想要释放一个内存空间,要找到所有指向它的指针进行一次release,并且每个指针只能释放一次,然后置空(避免误操作)。
- 多线程操作一个变量的时候,不确定哪个在线程中释放,因为线程执行时间不一。
ARC的缺点:
- 如果A引用B,B引用A。如果都用strong申明会导致循环引用问题。
2.@property关键字 strong,weak,assign,copy,retain的区别与问题
- assign一般用于CCRect之类的结构体以及基本数据类型,代码实现是直接赋值
- retain一般用于OC对象类型用于MRC模式,代码实现是 if(_temp != temp) { [_temp release]; _temp = [temp retain]}; return _temp;
- copy一般用于NSString类型以及Block,代码实现是 if(_temp != temp) { [_temp release]; _temp = [temp copy]}; return _temp;
- strong一般用于OC对象用于ARC模式,代表用强指针指向对象
- weak一般用于OC对象用于ARC模式,代表用弱指针指向对象
因为block默认申请的是栈内存,当block所在的方法执行完之后内存空间就被释放。为了可以在外部使用block,需要把block放入堆内存中。MRC中只有copy做到这一点,ARC中copy可以。
为什么NSString要用copy,而不用用strong? (block 字典 数组同理)
一个场景:如果用NSString指向一个NSMutableString的内存空间的话,用strong修饰。当NSMutableString中内容改变时,NSString指针指向的也会改变,而用copy不会
- 必须使用copy的场景:A对象持有string记做A.string,然后赋值给B对象,记做B.string,若希望B.string的内容改变时A.string不改变就必须用copy
- 必须用strong的场景:若希望B.string的内容改变时同时A.string也改变则必须用strong
浅拷贝与深拷贝的区别
前者浅拷贝就是只拷贝对象,但是属性不拷贝,拷贝出来的对象和原来的对象共用属性,即指向同一个属性地址
cocoa有如下规则:
- 如果是foundation框架中的不可变的类型如NSString,copy相当于浅拷贝
- mutableCopy怎么拷贝都是深拷贝
- 可变对象 copy也能深拷贝
3.关于循环引用问题
- 当A强引用B,B强引用A。这会让两个都有强指针指向结果都无法释放。解决办法把其中一个用weak申明
- 当block用copy属性修饰的时候,block会对其中用到的OC对象有强引用。解决办法把用到的oc对象用__weak声明,mrc用__block申明
4.什么情况会出现内存泄漏
- 当调用一些C语言的Api用完没有关闭(如利用UIGraphicsBeginImageContextWithOptions打开了图形上下文,没有close),导致资源没有释放
- 出现循环引用的情况,导致资源没有释放
- MRC中将OC对象的释放权利交给自动释放池,在池子被销毁前程序创建n个oc对象,将导致内存泄漏。