zoukankan      html  css  js  c++  java
  • ARC与Toll-Free Bridging

    arc模块与mrc模块的沟通。

    相当于程序的混编处理。

    Toll-Free Briding保证了在程序中,可以方便和谐的使用Core Foundation类型的对象和Objective-C类型的对象。

    There are a number of data types in the Core Foundation framework and the Foundation framework that can be used interchangeably. This capability, called toll-free bridging, means that you can use the same data type as the parameter to a Core Foundation function call or as the receiver of an Objective-C message. 

    Toll-Free Briding保证了在程序中,可以方便和谐的使用Core Foundation类型的对象和Objective-C类型的对象。详细的内容可参考官方文档。以下是官方文档中给出的一些例子:

    NSLocale *gbNSLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];

    CFLocaleRef gbCFLocale = (CFLocaleRef) gbNSLocale;

    CFStringRef cfIdentifier = CFLocaleGetIdentifier (gbCFLocale);

    NSLog(@"cfIdentifier: %@", (NSString *)cfIdentifier);

    // logs: "cfIdentifier: en_GB"

    CFRelease((CFLocaleRef) gbNSLocale);

    CFLocaleRef myCFLocale = CFLocaleCopyCurrent();

    NSLocale * myNSLocale = (NSLocale *) myCFLocale;

    [myNSLocale autorelease];

    NSString *nsIdentifier = [myNSLocale localeIdentifier];

    CFShow((CFStringRef) [@"nsIdentifier: " stringByAppendingString:nsIdentifier]);

    在MRC时代,由于Objective-C类型的对象和Core Foundation类型的对象都是相同的release和retain操作规则,所以Toll-Free Bridging的使用比较简单,但是自从加入后,类型的对象内存管理规则改变了,而依然是之前的机制,换句话说,不支持。

    这个时候就必须要要考虑一个问题了,Core FoundationObjective-C,用哪一种规则来管理对象的内存。显然,对于同一个对象,我们不能够同时用两种规则来管理,所以这里就Objective-CARCCore FoundationMRC或者说要确定对象类型转换了之后,内存管理的ownership的改变。

    If you cast between Objective-C and Core Foundation-style objects, you need to tell the compiler about the ownership semantics of the object using either a cast (defined in objc/runtime.h) or a Core Foundation-style macro (defined inNSObject.h)

    于是苹果在引入ARC之后对Toll-Free Bridging的操作也加入了对应的方法与修饰符,用来指明用哪种规则管理内存,或者说是内存管理权的归属。

    这些方法和修饰符分别是:

    __bridge(修饰符)

    只是声明类型转变,但是不做内存管理规则的转变。

    比如:

    @"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;

    // do something with s2

    //...

    // 注意要在使用结束后加这个

    我们在第二行做了转化,这时内存管理规则由ARC变为了MRC,我们需要手动的来管理s2的内存,而对于s1,我们即使将其置为nil,也不能释放内存。

    等同的,我们的程序也可以写成:

    NSString *s1 = [[NSString alloc] initWithFormat:@"Hello, %@!", name];

    CFStringRef s2 = (CFStringRef)CFBridgingRetain(s1);

    // do something with s2

    //...

    // 注意要在使用结束后加这个

    __bridge_transfer(修饰符) or CFBridgingRelease(函数)

    这个修饰符和函数的功能和上面那个__bridge_retained相反,它表示将管理的责任由Core Foundation转交给Objective-C,即将管理方式由MRC转变为ARC。

    比如:

    CFStringRef result = CFURLCreateStringByAddingPercentEscapes(. . .);

    NSString *s = (__bridge_transfer NSString *)result;

    //or NSString *s = (NSString *)CFBridgingRelease(result);

    s;

    这里我们将result的管理责任交给了ARC来处理,我们就不需要再显式地将CFRelease()了。

    对了,这里你可能会注意到一个细节,和ARC中那个4个主要的修饰符(__strong,__weak,...)不同,这里修饰符的位置是放在类型前面的,虽然官方文档中没有说明,但看官方的头文件可以知道。小伙伴们,记得别把位置写错哦:)

    012003323001197.png

    http://www.cnblogs.com/flyFreeZn/p/4264220.html

  • 相关阅读:
    spring源码解析四( spring事务)
    Epoll的本质(内部实现原理)转载
    Gitlab+Jenkins+Docker+K8S实现CI/CD
    AIOps
    云运维的关键有哪些?
    Nginx代理Portainer
    nginx+tomcat+mysql进行负载均衡
    Docker安装及容器创建
    运维常用的linux命令操作
    Arm64安装docker和docker-compose
  • 原文地址:https://www.cnblogs.com/feng9exe/p/10383675.html
Copyright © 2011-2022 走看看