__bridge_retained/__bridge_transfer/__bridge使用详解

第一、__bridge_retained的使用

__bridge_retained转换可使要转换的变量也持有所赋值的对象

void *p=0;

{

id obj=[[NSObject alloc] init];

p=(__bridge_retained void*)obj;

}

NSLog(@"class=%@",[(__bridge id)p class]);

输出结果:

class=NSObject

分析:

变量作用域结束后,虽然obj失效,__bridge_retained转换使变量p看上去处于持有该对象的状态,因此该对象不会被释放

第二、__bridge_transfer

当想把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权的时候,需要使用 __bridge_transfer 关键字。

如在非ARC环境下:

id obj = (id)p;

[obj retain];

[(id)p release];

在ARC环境下,使用__bridge_transfer,如下所示:

id obj = (__bridge_transfer id)p;

__bridge_retained是编译器为我们做了retain操作,__bridge_transfer是编译器为我们做了release

第三、在 Core Foundation框架中的使用

CoreFoundation对象是用C语言实现CoreFoundation Framework的对象,也有引用计数的概念,使用的关键词是CGRetain/CFRelease,

因为和Foundation结构相同,在非ARC下可以用C语言的类型转换,如下所示:

NSString *[email protected]"RichardYang";

CFStringRef strRef=(CFStringRef)str;

在ARC环境下,因为编译器会管理Foundation对象的内存,但CoreFoundation对象却不会处理,此时,使用关键词__bridge/__bridge_retained进行处理。

1、使用__bridge_retained

@autoreleasepool {

CFMutableArrayRef cfObject=nil;

{

id obj=[[NSMutableArray alloc] init];

cfObject=(__bridge_retained CFMutableArrayRef)obj;

//CFShow(cfObject);

printf("the retain count =%ld\n",CFGetRetainCount(cfObject));

}

printf("the retain count is %ld\n",CFGetRetainCount(cfObject));

CFRelease(cfObject);//如果不执行CFRelease则内存泄露

}

输出结果为:

the retain count =2

the retain count is 1

2.使用__bridge

只做类型转换,但是不修改对象(内存)管理权;

@autoreleasepool {

CFMutableArrayRef cfObject=nil;

{

id obj=[[NSMutableArray alloc] init];

cfObject=(__bridge CFMutableArrayRef)obj;

//CFShow(cfObject);

printf("the retain count =%ld\n",CFGetRetainCount(cfObject));

}

//printf("the retain count is %ld\n",CFGetRetainCount(cfObject));

CFRelease(cfObject);

}

CFRelease(cfObject);会抛异常,__bridge实现了转换,并没有保持对象。

3、使用__bridge_transfer

@autoreleasepool {

CFMutableArrayRef cfObject=CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);

printf("the retaincount is %ld\n",CFGetRetainCount(cfObject));

/*

* __bridge_transfer,对cfObject执行release操作,然后将对象赋给了obj,但是cfObject仍然指向存在的对象,可以正常使用

*/

id obj=(__bridge_transfer id)cfObject;

printf("after __bridge_transfer retaincount is %ld\n",CFGetRetainCount(cfObject));

NSLog(@"class=%@",obj);

}

/*

*obj跳出作用域,强引用失效,释放对象,没有内存泄露

*/

return 0;

时间: 2024-10-10 20:51:10

__bridge_retained/__bridge_transfer/__bridge使用详解的相关文章

__bridge,__bridge_transfer和__bridge_retained详解

Core Foundation 框架Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的服务: 群体数据类型 (数组.集合等)程序包字符串管理日期和时间管理原始数据块管理偏好管理URL及数据流操作线程和RunLoop端口和soket通讯Core Foundation框架和Foundation框架紧密相关,它们为相同功能提供接口,但Foundation

JSPatch实现原理详解<二>

本文转载至 http://blog.cnbang.net/tech/2855/ 距离上次写的<JSPatch实现原理详解>有一个月的时间,在这段时间里 JSPatch 在不断地完善和改进,代码已经有很多变化,有一些修改值得写一下,作为上一篇的补充. Special Struct 先说下 _objc_msgForward,在上一篇提到为了让替换的方法走 forwardInvocation,把它指向一个不存在的 IMP: class_getMethodImplementation(cls, @se

ios新特征 ARC详解

IOS ARC 分类: IOS ARC2013-01-17 09:16 2069人阅读 评论(0) 收藏 举报 目录(?)[+] 关闭工程的ARC(Automatic Reference Counting) 顺带附上ARC教程 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流和讨论.请不要将本文的部分或全部内容用于商用,谢谢合作. 欢迎转载本文,但是转载请注明本文出处:http://www.onevcat.com/2012/06/arc-hand-by

ARC机制之__strong详解

ARC机制之__strong详解 __strong  解析: 默认情况下,一个指针都会使用 __strong 属性,表明这是一个强引用.这意味着,只要引用存在,对象就不能被销毁.这是一种所期望的行为:当所有(强)引用都去除时,对象才能被收集和释放. 不过, 有时我们却希望禁用这种行为:一些集合类不应该增加其元素的引用,因为这会引起对象无法释放.在这种情况下,我们需要使用弱引用(不用担心,内置的集合类 就是这么干的),使用 __weak 关键字.NSHashTable 就是一个例子.当被引用的对象

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

HttpServletResponse和HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20