zoukankan      html  css  js  c++  java
  • iOS Fundation和CoreFoundation的对象转换内存管理权问题

    iOS Fundation和CoreFoundation的对象转换

    1、对象转换时涉及到内存管理权的问题

    背景:Foundation框架和CoreFoundation框架分别是由C语言和OC语言实现的苹果官方库。
    就是由于是由不同的语言实现的,在iOS5之后,OC开始支持ARC内存管理。在MRC时代,内存的管理全部要有程序员自己来完成,不涉及内存管理权的移交问题。但是在ARC时代,在Foundation 和 CoreFoundation框架之间的一些对象要相互转换,就必须要考虑内存管理权的问题。两个不同框架生成的对象强制转换时,需要交代清楚到底是让ARC帮我们管理内存还是要我们自己手动管理内存。
    苹果提供了3个关键词来解决这一问题,分别是__bridge, __bridge_retain, __bridge_transfer。

    2、__bridge关键字

    /*
         __bridge 关键字,它的含义是不改变对象管理权的所有者,本来由ARC管理的Foundation对象,转换成Core Foundation 对象后依然由ARC管理;本来由开发者手动管理的Core Foundation对象转换为Foundation 对象后继续由开发者手动管理
         */
        /*ARC 管理的Foundation对象*/
        NSString *s1 = @"111";
        /*转换后,依然有ARC 管理内存*/
        CFStringRef cfStr = (__bridge CFStringRef)s1;
        /*开发者手动管理的 CoreFoundation对象*/
        CFStringRef s2 = CFStringCreateWithCString(NULL, "cf create string", kCFStringEncodingASCII);
        /*转换后仍然需要开发者手动管理释放*/
        NSString *fstring = (__bridge NSString*)s2;
    
        NSLog(@"s1: %@", s1);
        NSLog(@"cfStr: %@", cfStr);
        NSLog(@"s2: %@", s2);
        NSLog(@"fstring: %@", fstring);
        
    

    如果不做特殊处理s2有内存泄漏的危险:
    跑一下代码,做一个内存分析可以发现,Xcode 已经开始抱怨了:
    这里是控制台打印:

    这里是运行时危险警告:

    我们打印下报错地址对应的内容,发现就是 s2:

    2、__bridge_transfer关键字

    /*
         __bridge_transfer用在将Core Foundation对象转换成Foundation对象时,进行对象管理权的移交。即本来需要由开发者手动管理和释放的Core Foundation 对象在转换成Foundation对象后,交由ARC来管理对象的释放。开发者不需要再关注对象内存释放的问题。
         */
        /*开发者手动管理的Core Foundation对象*/
        CFStringRef cfStr2 = CFStringCreateWithCString(NULL, "cf creat string2", kCFStringEncodingASCII);
        /*转换后改由ARC管理对象的释放,不用担心内存的泄漏*/
        NSString *str2 = (__bridge_transfer NSString *)cfStr2;
        /*等效写法*/
       //NSString *str2 = (NSString *)CFBridgingRelease(cfStr2);
    

    3、__bridge_obtain关键字

       /*
         __bridge_retain 用在将Foundation对象转换成 Core Foundation对象时,进行ARC对象管理权的剥夺。即本来由ARC管理的Foundation对象在转换为Core Foundation对象时,ARC不再继续管理,需要开发者自己手动释放对象所占用的内存,否则会发生内存泄漏。
         */
        /*ARC管理的Foundatioin对象*/
        NSString *s3 = @"string3";
        /*转换后ARC不再继续管理,需要手动释放*/
        CFStringRef cfString3 = (__bridge_retained CFStringRef)s3;
        //另一种写法
        //CFStringRef cfString4 = (CFStringRef)CFBridgingRetain(s3);
    
  • 相关阅读:
    [leetcode] Bulls and Cows
    Win7 系统所有应用颜色调整
    一道题反映Java的类初始化过程
    翻转二叉树(深搜-先序遍历-交换Node)
    在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1)
    一道随机函数题:由rand5()生成rand7()
    求一条直线通过的最大点数
    菜根谭#236
    菜根谭#235
    菜根谭#234
  • 原文地址:https://www.cnblogs.com/wjw-blog/p/14469766.html
Copyright © 2011-2022 走看看