ARC与MRC

一、通过引用计数管理内存

1、引用计数。通过引用计数管理内存。对象被创建出来时,引用计数至少为1,通过retain使引用计数递增,通过release、autorelease使引用计数递减,引用计数为0时,对象所在的内存为可重用,所有指向该对象的引用都无效。

2、dangling pointer。指向对象的引用计数为0的引用。使用dangling pointer不一定使程序崩溃,崩溃是否,看对象内存是否被覆写。

3、引用树。ios应用程序中的root object为UIApplication对象。

4、属性存取。strong relationship修饰的属性,在setValue时,先保留新值,再释放旧值。这个顺序不能颠倒,一旦颠倒,假如新值和旧值为同一个对象,释放后有可能对象已被回收,再保留就会出现问题。

5、autorease。在return方法内部创建的对象时,由于不能在方法内部释放对象(对象引用计数值有可能为0,对象就被回收),就得通过autoreleasepool使引用计数值在下一次event loop时递减。通过类工厂方法创建的对象放置在autoreleasepool中。

6、retain cycle。导致内存泄漏,解决问题有两种办法,一是weak reference,一是代码控制其中的某个对象不再保留另外一个对象。

7、Clang编译器中的静态分析器(static analyzer)。可以查明内存管理问题,也可以根据需要,预先加入保留与释放操作。

注意:retaincount方法获取引用计数值是不太有用的。对引用计数器做递增或递减操作时,只能说做了递增或递减操作,而绝不能说保留计数一定是某个值。

二、ARC自动引用计数(编译器与运行期组件共同管理内存)

1、实现思路是static analyzer。

2、代码中存在retain、release、autorelease、dealloc时,编译器无法通过。在调用这些方法时,不通过oc的消息派发机制,直接调用底层的c语言函数。

3、ARC命名规则。以alloc、new、copy、mutableCopy开头的方法名,对象归方法调用者持有。详解如下:

/* newPerson方法中,方法调用者持有返回对象。因此在方法内部,除了allo使引用计数+1外,没有其余的保留与释放操作,最后在调用方法后,对象需要增加一次释放操作。*/
+ (Person *)newPerson{
    Person *person = [[person alloc] init];
    return person;
}
/*createPerson方法中,方法调用者不持有返回对象,因此在return操作时,ARC会增加 [person autorelease] 方法。最后计数器平衡。*/
+ (Person *)createPerson{
    Person *person = [[person alloc] init];
    return person;
}

4、ARC有时会成对移除保留、释放操作。

5、ARC包含运行期组件。

如果方法名没遵守命名规则,但返回值赋值给强引用修饰的变量,无疑需要增加retain操作。考虑到backward compatibility性能,createPerson方法的return语句不用[person autorelease]替换,而改用objc_autoreleaseReturnValue(person)替换。

objc_autoreleaseReturnValue方法底层实现。此方法会检视方法返回后,是否要执行retain操作。如果要执行retain操作,则会设置全局数据结构中的一个标志位,并且方法中的return对象不会自动释放。而且在执行retain操作时,[person retain]也会用 objc_retainAutoreleaseReturnValue(person)方法代替,检查到标志位已经置位,则不执行保留操作。

设置标志位和检查标志位是否已置位(编译器执行),比保留和释放快。

6、ARC中局部变量与实例变量修饰符。

strong:保留此值,默认语义;

weak:不保留此值,并且值被回收后,指向nil;

7、ARC中的dealloc方法。

1)、dealloc方法不允许发送release消息,不允许给父类发送dealloc消息。ARC借助Objective-C++的一项特性生成清理例程(Objective-C++特性:回收Objective-C++对象时,待回收对象会调用所有C++对象的析构函数,编译器发现对象中存在C++对象,就会生成.cxx_destruct方法),在.cxx_destruct方法中自动生成代码,包括给父类发送dealloc消息。单例对象不会自动析构。

2)、必要时添加CFRealease(Core Foundation对象)、free(通过malloc()分配的内存)方法、注销通知等等。ARC中的dealloc方法仅释放引用并解除监听。

3)、释放引用不包括file descriptor、socket、大块内存等,通常创建另一个方法来释放这些引用,且另一个方法的调用必须在dealloc执行之前。不在dealloc中释放这些资源的原因:一是通过dealloc释放,资源保留时间过长;二是dealloc方法不一定执行。

4)、执行异步任务的方法不应在dealloc中调用,只能在正常状态下执行的方法也不应在dealloc中调用。

8、ARC中可能出现内存泄露的地方:

1)、出现相互强引用,导致双方都无法释放(retain cycle);

2)、c代码的对象,是不会自己释放的,比如cg(CoreGraphics.frameworks)开头的对象。

3)、GCD对象。

时间: 2024-10-10 06:04:21

ARC与MRC的相关文章

iOS开发ARC与MRC下单例的完整写法与通用宏定义

#import "XMGTool.h" /** * 1:ARC下的完整的单例写法:alloc内部会调用+(instancetype)allocWithZone:(struct _NSZone *)zone方法,所以重写该方法,用GCD一次性函数,默认是线程安全的加了一把锁,也可以自己去加锁 @synchronized(self) { if (_instance == nil) { _instance = [super allocWithZone:zone]; } } 2:还要考虑cop

iOS arc VS mrc学习笔记

一.* Core Foundation与objective-c Object进行交换 * 对于Core Foundation与objective-cObject进行交换时,需要用到的ARC管理机制有: (1) (__bridge_transfer) op or alternatively CFBridgingRelease(op) is used to consume a retain-count of a CFTypeRef while transferring it over to ARC.

iOS内存管理 ARC与MRC

想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC).OC的内存管理机制叫做引用计数,就是一块内存地址可以同时被多个对象引用,每引用一次,引用计数都会递增1,当对象每解除一次引用,引用计数就会递减1,直到引用计数为0时,系统才会讲这块内存地址回收释放掉,这与C/C++语言有些不同,但是它们都遵守同一个内存管理法则:谁申请,谁释放. 在早些时候,iO

ARC以及MRC中setter方法

ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下ARC下的setter方法: 小结: 1. 一旦你重写了getter.setter方法,你必须使用@synthesize variable = _variable来区分属性名与方法名. 2. ARC与MRC的getter方法一致,就setter方法有着略微区别.

Block在内存中的位置在arc和mrc的区别

关于block在内存中的位置, http://tanqisen.github.io/blog/2013/04/19/gcd-block-cycle-retain/这篇文章解释的不错,但是好像并没有区分arc和mrc的区别 block的位置分为这几种 NSGlobalBlock:类似函数,位于text段: NSStackBlock:位于栈内存,函数返回后Block将无效: NSMallocBlock:位于堆内存. 不引用外部环境变量的block都属于NSGlobalBlock, NSStackBl

@autoreleasepool在ARC和MRC下的区别

MRC这个词应该是我编的,ARC,Automatic Reference Counting,手工引用计数就应该是:Manual Reference Counting,那就应该是MRC喽,不过没有见人这样用过. ARC引入了新的语句管理自动释放池语法: @autoreleasepool {     // Code, such as a loop that creates a large number of temporary objects.} 测试了一下,在ARC情况下和MRC情况下对象的释放有

ios-实现ARC与MRC混编

选择target -> build phases -> compile sources -> 用ARC的文件将compiler flags设置为:-fobjc-arc,用MRC的文件将compiler flags设置为:-fno-objc-arc. 同样,如果一个项目用ARC,而某个文件需要用MRC,只需要在compiler sources中将该文件的 compiler flags设置为-fno-objc-arc即可. ios-实现ARC与MRC混编

ARC以及MRC中setter方法的差异

ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下ARC下的setter方法: 小结: 1. 一旦你重写了getter.setter方法,你必须使用@synthesize variable = _variable来区分属性名与方法名. 2. ARC与MRC的getter方法一致,就setter方法有着略微区别. ARC以及MRC中setter方法的差

单例模式 - GCD 、兼容ARC和MRC

单例模式 - GCD .兼容ARC和MRC 单例模式的作用: 1,可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问 2,从而方便地控制了实例个数,并节约系统资源 单例模式的使用场合: 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次) 单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码 可以用宏判断是否为ARC环境 #if __has_feature(objc_arc) //ARC #else //MRC #endif 在游戏中,音乐在不同的场景

ARC、MRC混编

Xcode5之后,新建iOS工程,默认都是ARC模式,但是有时候我们的项目中需要用到一些第三方框架,我们下载下来却发现是非ARC的,这时候我们需要进行ARC和MRC混编. 第一种方式: Edit->Refactor,转换成ARC方式 著名的iOS网络框架ASIHTTPRequest就是MRC,我们试试能不能转换成ARC 点击Check,我们发现悲剧了 多数情况下这种方式都会出错,那该怎么办呢? 第二种方式: 给编译器加标记 可以在Build Phases中的Compile Sources中加入编