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);
    
  • 相关阅读:
    Server08 R2 Live Migration 测试 Part 6:使用SCVMM 2008 R2进行Live Migration
    Workstation 可成功安装ESX但发现不到本地存储的解决方法
    代码生成器ltscode2.1
    2010面试攻略
    我看代码生成
    程序员如何提高工作效率
    PE格式全分析
    Quartz.NET 2.0 学习笔记(4) :cron表达式
    asp.net 2.0 访问 MySQL 数据库
    My blog.
  • 原文地址:https://www.cnblogs.com/wjw-blog/p/14469766.html
Copyright © 2011-2022 走看看