ARC内存管理技术

一.ARC的本质
ARC是编译器时特性,而不是运行时的特性,更不是垃圾回收机制(GC)。

二.ARC的开启和关闭
如果需要对特定文件开启或关闭ARC,可以在工程选项中选择Targets->Compile Phases->Compile Source,在里面找到对应文件,添加flag。
打开ARC:-fobjc-arc
关闭ARC:-fno-objc-arc

三.ARC的修饰符
ARC主要提供了4种修饰符,他们分别是:__strong,__weak,__autoreleasing,__unsafe_unretained。
__strong
表示引用为强引用。对应在定义property时的"strong"。所有对象只有当没有任何一个强引用指向时,才会被释放。
如果在声明引用时不加修饰符,那么引用将默认为强引用。当需要释放一个强引用指向的对象时,需要将强引用置为nil。

__weak
表示引用为弱引用。对应在定义property时的"weak"。弱引用不会影响对象的释放,即只要对象没有任何一个强引用指向,即使有100个弱引用对象指向也没用,该对象依然会被释放。不过好在,对象在释放的同时,指向它的弱引用会自动被置为nil,这个技术叫zeroing weak pointer。 这样有效的防止无效指针,野指针的产生。__weak一般用在delegate关系中防止循环引用或者用来修饰指向由Interface Builder编译与生成的UI控件。

__autoreleasing
表示在autorelease pool中自动释放对象的引用,和MRC时代autorelease的用法相同。定义property时不能使用这个修饰符,任何一个对象的property都不应该是autorelease类型的。

__unsafe_unretained
ARC是ios5引入的,而这个修饰符主要是为了在ARC刚发布时兼容ios4以及版本更低的设备,因为这些版本的设备没有weak pointer system,简单的理解这个系统就是我们上面讲weak时提到的,能够在weak引用指向对象被释放后,把引用值自动设为nil的系统。
现在可以完全忽略这个修饰符了。


四.使用修饰符的正确姿势
ClassName * qualifier variableName
NSString * __weak str = @"hehe" //正确
__weak NSString *str = @"hehe" //错误

五.栈中指针默认值为nil
无论是被strong,weak还是autoreleasing修饰,声明在栈中的指针默认值都会是nil。所有这类型的指针不用再初始化的时候设置nil了。这个特性更加降低了"野指针"出现的可能性。


六.ARC与Block
在MRC时代,Block会隐式地对进入其作用域内的对象加retain,来确保Block使用到该对象时,能够正确的访问。
__block在MRC时代有两个作用
1.说明变量可改。
2.说明指针指向的对象不做这个隐式的retain操作。
__block在ARC时代只有一个作用
1.说明变量可改


七.ARC与Toll-Free Bridging
在MRC时代,由于Objective-c类型的对象和Core Foundation类型的对象都是相同的release和retain操作规则,所以Toll-Free Bridging的使用比较简单。但是自从ARC加入后,Objective-c类型的对象内存管理规则改变,而Core Foundation依然是之前的机制,换句话说,Core Foundation不支持ARC。
于是苹果在引入ARC之后对Toll-Free Bridging的操作也加上了对应的方法与修饰符,用来指明哪种规则管理内存,或者说是内存管理权的归属。
 __bridge
只是声明类型转变,但是不做内存管理规则的转变。
CFStringRef s1 = (__bridge CFStringRef)[[NSString alloc] initWithFormat:@"Hello,%@!",name];
只是做了NSString到CFStringRef的转化,但管理规则未变,依然要用Objective-c类型的ARC来管理s1,你不能用CFRelease()去释放s1。

__bridge_retained(修饰符) or CFBridgingRetain(函数)
表示将指针类型转变的同时,将内存管理的责任由原来的Objective-c交给Core Foundation来处理,也就是,将ARC转变为MRC
NSString *s1 = [[NSString alloc] initWithFormat:@"Hello,%@!",name];
CFStringRef s2 = (__bridge_retained CFStringRef)s1;
CFRelease(s2);

NSString *s1 = [[NSString alloc] initWithFormat:@"Hello,%@!",name];
CFStringRef s2 = (CFStringRef)CFBridgingRetain(s1);
CFRelease(s2);

__bridge_transfer(修饰符) or CFBridgingRelease(函数)
表示将管理的责任由Core Foundation转交给Objective-c,即将管理方式由MRC转变为ARC
CFStringRef result = CFURLCreateStringByAddingPercentEscapes(...);
NSString *s = (__bridge_transfer NSString*)result;
// or NSString *s = (NSString *)CFBridgingRelease(result);
return s;


























 








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值