浅谈oc的内存管理MRC与ARC

一、c中程序的内存区域分配


1、栈区(stack)—  存放函数的参数值,局部变量的值等,由编译器自动分配释放。

2、堆区(heap) —   一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(data段中的静态区),   未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(bbs段),程序结束后由系统释放。

4、文字常量区   —常量字符串就是放在这里的,程序结束后由系统释放。

5、程序代码区—存放函数体的二进制代码。

栈区存放一些基础类型,是一块连续存储的空间,遵循先进后出的原则,但是当数据量比较大的时候,降低性能,我们会把地址存放在栈中,数据存放在堆中,所以说系统不会自动释放堆中的内存的,希望我们程序员自己释放的。

二、MRC


1、引用计数器

我们知道当生成的对象还有被引用时,就不能被释放,那这个对象什么时候被释放呢,OC在内存管理上用了引用计数器(retain count), 在对象内部保存一个数字,当new copy(mutablecopy) retain alloc的时候retaincount+1;当调用release时retaincount-1;当retain count等于0的时候,系统才会调用dealloc方法来销毁对象。

2、内存管理原则:谁创建谁释放,谁retain谁释放

                          配对原则,retain和release是配对的,retain>release内存泄露

3、set方法

- (void)setClass:(ClassA*)class {

[class retain];

[_class release];

_class=class;

}或

- (void)setClass:(ClassA*)class {

if(_class!=class){

[_classrelease];

[classretain];

_class=class;

}

}

4、属性与内存管理

@property实际上是getter和setter,@synthesize是合成这2个方法。

5、自动释放池

自动释放池相当于半自动的释放,存储在自动释放池的对象,在自动释放池销毁时,会自动调用该对象的release方法,故将对象存储在自动释放池中,就不需要再写release,相当于延迟释放.

intmain(intargc,constchar* argv[]) {

@autoreleasepool{

ClassA*a=[[ClassAalloc]init];

[aautorelease];

a.num=@"111";//这时候还没有释放

return0;

}

}

只有在自动释放池中调用了对象的autorelease方法,这个对象才会被存储到这个自动释放池之中,当自动释放池结束的时候.仅仅是对存储在自动释放池中的对象发送1条release消息 而不是销毁对象.

三、ARC


1、ARC是编译时编译器会自动的在合适的地方插入retain、release、autorelase代码;编译器自动为对象做引用计数.而大大节约了开发者人员的工作。

2、属性与内存管理

strong,和copy相当于mrc会在set,get的时候将引用计数加一,咱们要注意避免循环引用,造成内存泄露,将其中一个用weak.

3、ARC只对3类 retainable object pointers(ROPs)起作用:

Block 指针;

Objective-C 对象指针;

_attribtue_((NSObject))标记的typedef .

所有其他的指针如 char*, CF对象如 CFStringRef,malloc c array等,都不是ARC支持的,需要自己手动处理。

4、Objective-C和 Core Foundation 对象相互转换

Core Foundation是用c提供的接口,可以和OC的一些对象进行相互的转换。

CFStringRef aCFString = (CFStringRef)aNSString;

NSString *aNSString = (NSString *)aCFString;

在MRC的情况下相互转换之后释放就好,但是在ARC的情况下怎么考虑呢

1. __bridge_retained 或者 CFBridgingRetain()

__bridge_retained 或者 CFBridgingRetain()  将Objective-C对象转换为Core Foundation对象,把对象所有权桥接给Core Foundation对象,后续需要开发者使用CFRelease或者相关方法手动来释放对象。

2. __bridge_transfer 或者 CFBridgingRelease()

__bridge_transfer 或者 CFBridgingRelease()  将非Objective-C对象转换为Objective-C对象,同时将对象的管理权交给ARC,开发者无需手动管理内存。

3. __bridge

__bridge 只做类型转换,不改变对象所有权,是Core Foundation手动释放,不是就自动释放

四、参考


http://blog.csdn.net/yiyaaixuexi/article/details/8553659

http://www.cnblogs.com/kenshincui/p/3870325.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容