当前位置: 首页 > news >正文

Objective-C 初阶 —— __bridge __bridge_retained __bridge_transfer

一、ARC & MRC

1、ARC

ARC 就是自动引用计数. 每当一块内存被一个强引用(指针)指着, 这块内存的引用计数自动 +1, 而每当一个强引用(指针)被销毁或置空后, 这块内存的引用计数会自动 -1.

当然, 无论是 ARC 还是 MRC, 只要这块内存的引用计数为 0, 那么这块内存就会被自动释放.

2、MRC

MRC 就是手动引用计数. 就是指针(引用)的指与不指都不会影响内存的引用计数. 只有当你每调一次 retain / CFRetain, 这块内存的引用计数才会 +1; 每调一次 release / CFRelease, 这块内存的引用计数才会 -1.

当然, 只有当这块内存的总引用计数 (ARC 侧 + MRC 侧) 为 0 时, 这块内存才会被释放.

二、__bridge & __bridge_retained & __bridge_transfer

1、__bridge

__bridge 只会基于 Core Foundation 的引用创建一个 Foundation 里的引用, 或基于 Foundation 引用创建一个 Core Foundation 的引用; 并不会自动帮你调 CFRetain 或 CFRelease.

但需要注意的是: 如果你在 Core Foundation 侧通过 __bridge 创建一个 Foundation 侧的引用, 由于这块内存被 Foundation 侧的引用指着, 而 Foundation 是遵循 ARC 的, 因此 ARC 侧会增加一个引用计数, 于是这块内存总的引用计数 (CoreFoundation/MRC 侧 + Foundation/ARC 侧) 就会 +1.

2、__bridge_retained

__bridge_retained 会基于 Foundation 的引用创建一个 Core Foundation 的引用, 然后自动帮你调一次 CFRetain() 函数.

因此 __bridge_retained 会自动为 MRC 侧增加一个引用计数, 导致这块内存的总引用计数 (CoreFoundation/MRC 侧 + Foundation/ARC 侧) +1.

3、__bridge_transfer

__bridge_transfer 会基于 CoreFoundation 侧的引用创建一个 Foundation 侧的引用, 然后再自动帮你调一次 CFRelease() 函数.

因此 __bridge_transfer 会自动为 CoreFoundation/MRC 侧减少一个引用计数; 同时因为 Foundation 侧遵循 ARC, 所以 ARC 侧又会增加一个引用计数, 因此这块内存总的引用计数 (CoreFoundation/MRC 侧 + Foundation/ARC 侧) 是没变的.

三、Demo 展示

如果大家想看更直观的对比, 可以在 command line tool 拷贝下面的代码, 看看引用计数的变化.

//
//  main.m
//  toll-free bridge
//
//  Created by chuanzhima on 2025/10/26.
//#import <Foundation/Foundation.h>#define PRINT_RC(obj, name) NSLog(@"[RC] %@ (%p): %ld", name, obj, CFGetRetainCount((__bridge CFTypeRef)obj))void demo_bridge_retained(void) {NSLog(@"\n--- Demo 1: __bridge_retained ---");// 1️⃣ ARC 创建一个堆对象NSMutableString *str_arc = [[NSMutableString alloc] initWithString:@"Hello Retained"];PRINT_RC(str_arc, @"初始 str_arc");// 预期 RC = 1// 2️⃣ __bridge_retained:增加 RC,ARC 不再管理CFStringRef cfStr = (__bridge_retained CFStringRef)str_arc;PRINT_RC((__bridge id)cfStr, @"__bridge_retained 之后");// 3️⃣ ARC 侧清空引用str_arc = nil;NSLog(@"ARC 清空 str_arc");PRINT_RC((__bridge id)cfStr, @"str_arc 置 nil 后");// 4️⃣ CF 侧转换为 F 侧NSMutableString *str_arc1 = (__bridge NSMutableString *)cfStr;NSLog(@"CF 侧转换为 F 侧");PRINT_RC(str_arc1, @"CF 侧转换为 F 侧后");str_arc1 = nil;PRINT_RC((__bridge id)cfStr, @"str_arc1 置空后");// 5️⃣ 手动释放 CF 持有的引用CFRelease(cfStr);NSLog(@"手动 CFRelease 后,对象应释放\n");
}void demo_bridge_transfer(void) {NSLog(@"\n--- Demo 2: __bridge_transfer ---");// 1️⃣ CF 创建对象(手动管理)CFMutableStringRef cfStr = CFStringCreateMutableCopy(NULL, 0, CFSTR("Hello Transfer"));PRINT_RC((__bridge id)cfStr, @"初始 cfStr");// 2️⃣ __bridge_transfer:ARC 接管并 CFRelease 一次NSString *str_arc = (__bridge_transfer NSString *)cfStr;PRINT_RC(str_arc, @"__bridge_transfer 之后");// 3️⃣ 作用域结束,ARC 自动释放 str_arcNSLog(@"str_arc 即将离开作用域 (ARC 将自动释放)\n");
}void demo_bridge(void) {NSLog(@"\n--- Demo 3: __bridge ---");// 1️⃣ CF 创建对象(手动管理)CFMutableStringRef cfStr = CFStringCreateMutableCopy(NULL, 0, CFSTR("Hello Bridge"));PRINT_RC((__bridge id)cfStr, @"初始 cfStr");// 2️⃣ __bridge:仅类型转换,不改变所有权NSString *str_arc = (__bridge NSString *)cfStr;PRINT_RC(str_arc, @"__bridge 转换后");// 3️⃣ ARC 不会负责释放,需要手动 CFReleaseCFRelease(cfStr);NSLog(@"手动 CFRelease 完成 (ARC 不参与)\n");
}int main(int argc, const char *argv[]) {@autoreleasepool {demo_bridge_retained();demo_bridge_transfer();demo_bridge();}return 0;
}

http://www.dtcms.com/a/532888.html

相关文章:

  • wordpress主题6企业优化网站
  • 最细Maven教程以及Maven私服搭建
  • wordpress网站打开速度学设计网站
  • UVa 1298 Triathlon
  • cuda编程笔记(33)--Thrust库的使用
  • Gorm(十一)事务
  • Ubuntu24.04安装好Mysql8后,检查mysql占用的内存和磁盘
  • 阿里云申请域名后网站海外网络加速器
  • Orleans ILifecycleParticipant 生命周期管理详细分析
  • 企业门户网站建设方案后台管理wordpress多级tree分类目录
  • Spring XML AOP配置实战指南
  • 什么人需要网站建设柳州网站开发公司
  • 做纯净系统的网站产品做国外网站有哪些
  • 商贸公司网站建设兴城泳装电子商务网站建设
  • 张祥前统一场论中的洛伦兹变换:多层次的应用与全新内涵
  • 网安面试题收集(4)
  • 高端上海网站设计公司价格wordpress 打赏
  • Yolo_lableimg_env
  • 【09】C语言中的格式输入函数scanf()详解
  • 鼠键共享工具
  • 个人网站备案 拍照装修网店
  • 投资,如何获得估值回归的收益?
  • 专业上海网站建设公司排名住房和城乡建设部网站杂志
  • 边界扫描测试原理 4 -- 保持状态
  • 国外服务器网站打开慢重庆公司起名
  • 个人怎样做旅游网站清新太和做网站
  • 电商系统设计:运费
  • Ceph分布式存储
  • 网站建设销售职责网站开发与运维收费明细
  • 破解空间网站十堰网站建设怎么做