精品 CF与OBJC在ARC下的内存管理。

精品 CF与OBJC在ARC下的内存管理。,第1张

概述http://wangjun.easymorse.com/?p=1490 «  ios本地通知和远程通知 创建一个Storyboard工程 » Managing Toll-Free Bridging 在cocoa application的应用中,我们有时会使用Core Foundation(CF),我们经常会在Objective-C和CF之间进行转化。系统使用arc的状态下,编译器不能自动管理CF

http://wangjun.easymorse.com/?p=1490


«  ios本地通知和远程通知 创建一个Storyboard工程 » Managing Toll-Free BrIDging

在cocoa application的应用中,我们有时会使用Core Foundation(CF),我们经常会在Objective-C和CF之间进行转化。系统使用arc的状态下,编译器不能自动管理CF的内存,这时候你必须使用CFRetain和CFRelease来进行CF的内存的管理。

具体的CF内存管理规则见: Memory Management Programming Guide for Core Foundation

在OC和FC之间进行转化的时候,主要是对象的归属问题。共有两种方式:

1、使用宏,可以标识归属者从OC到CF,还是从CF到OC。

NS_INliNE CFTypeRef CFBrIDgingRetain(ID X) { 
    return (__brIDge_retain CFTypeRef)X; 

  
NS_INliNE ID CFBrIDgingrelease(CFTypeRef X) { 
    return (__brIDge_transfer ID)X; 
}

2、使用转化符,如:__brIDge,__brIDge_transfer,__brIDge_retained

ID my_ID; 
CFStringRef my_cfref; 
… 
Nsstring   *a = (__brIDge Nsstring*)my_cfref;     // Noop cast. 
CFStringRef b = (__brIDge CFStringRef)my_ID;      // Noop cast. 
… 
Nsstring   *c = (__brIDge_transfer Nsstring*)my_cfref; // -1 on the CFRef 
CFStringRef d = (__brIDge_retained CFStringRef)my_ID;  // returned CFRef is +1

下面以详细的例子来介绍一下OC和CF在arc下内存管理的详细写法.下面以CFURLCreateStringByAddingPercentEscapes()函数为例说一下在ARC下的写法和非ARC下的写法。

非ARC模式下的写法:

#pragma mark – VIEw lifecycle 
- (voID)vIEwDIDLoad 

    [super vIEwDIDLoad]; 
    NSLog(@"=%@",[self escape:@"wangjun"]); 

-(Nsstring *)escape:(Nsstring *)text 

    return (Nsstring *)CFURLCreateStringByAddingPercentEscapes( 
                                                                      NulL, 
                                                                      (__brIDge CFStringRef)text, 
                                                                      NulL, 
                                                                      CFSTR("!*’();:@&=+$,/?%#[]"),CFStringConvertnsstringencodingToEnCoding(NSUTF8StringEnCoding));; 
}

使用instruments检测,没有内存泄漏。

下面把上面工程改为arc模式。

可以看到xcode自动把上面函数转化为:


-(Nsstring *)escape:(Nsstring *)text 

    return (__brIDge_transfer Nsstring *)CFURLCreateStringByAddingPercentEscapes( 
                                                                      NulL,CFStringConvertnsstringencodingToEnCoding(NSUTF8StringEnCoding));; 
}

在arc中,CF和OC之间的转化桥梁是 __brIDge,有两种方式:

__brIDge_transfer  ARC接管管理内存 __brIDge_retained  ARC释放内存管理

上面的方法是从CF转化为OC Nsstring对象,使用的__brIDge_transfer ,对象所有者发生转变,由CF到OC,最后由ARC接管内存管理。运行上面的代码,用instruments检测,是没有内存泄漏的。

上面代码等同于:

- (Nsstring *)escape:(Nsstring *)text 

return CFBrIDgingrelease(CFURLCreateStringByAddingPercentEscapes( 
NulL, 
(__brIDge CFStringRef)text, 
NulL, 
CFSTR("!*’();:@&=+$,CFStringConvertnsstringencodingToEnCoding(NSUTF8StringEnCoding)));}

如果将上述代码改为:

-(Nsstring *)escape:(Nsstring *)text 

    return (__brIDge Nsstring *)CFURLCreateStringByAddingPercentEscapes( 
                                                                      NulL,CFStringConvertnsstringencodingToEnCoding(NSUTF8StringEnCoding));; 
}

编译也会成功,但是这时候用instruments检测,可以发现内存泄漏:

由于CF转化完OC,没有自己释放内存,同时也没有把内存管理交给ARC,所以出现内存泄漏。由于__brIDge只是同一个对象的引用,内存的所有权没有发生变化。

下面在说一下oc到CF的转化,需要把OC的内存管理权释放掉。

Nsstring *s1 = [[Nsstring alloc] initWithFormat:@"Hello,%@!",@R_502_6889@]; 
CFStringRef s2 = (__brIDge_retained CFStringRef)s1; 
// do something with s2 // . . . 
CFRelease(s2);

最后由CF进行内存释放。

上面代码等同于:

CFStringRef s2 = CFBrIDgingRetain(s1); 
// . . . 
CFRelease(s2);

下面总结一下我们使用ARC情况下。oc和CF互相转化的原则:

CF转化为OC时,并且对象的所有者发生改变,则使用CFBrIDgingrelease()或__brIDge_transfer 。 OC转化为CF时,并且对象的所有者发生改变,则使用CFBrIDgingRetain()或__brIDge_retained 当一个类型转化到另一种类型时,但是对象所有者没有发生改变,则使用__brIDge. ARC  Core Foundation  iOS  Objective-C 总结

以上是内存溢出为你收集整理的精品 CF与OBJC在ARC下的内存管理。全部内容,希望文章能够帮你解决精品 CF与OBJC在ARC下的内存管理。所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1061240.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存