You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARC中__bridge_transfer与CFBridgingRelease结果不一致问题咨询

为什么ARC下CFBridgingRelease和__bridge_transfer的结果不一致?

兄弟,我太懂你这困惑了——按道理ARC环境里CFBridgingRelease和__bridge_transfer应该是完全等价的,但你的代码测出来的 retain count 却不一样,对吧?咱们来一步步拆解问题出在哪。

先把你的代码贴出来方便分析:

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
        CFMutableArrayRef cfObject = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); 
        printf("retain count = %ld\n", CFGetRetainCount(cfObject)); 
        //id obj = (__bridge_transfer id)(cfObject); 
        id obj = CFBridgingRelease(cfObject); 
        printf("retain count after the cast = %ld\n", CFGetRetainCount(cfObject)); 
        NSLog(@"class=%@", obj); 
    }
}

核心问题:你在操作一个已经失效的指针!

首先得明确一个关键事实:CFBridgingRelease本质上就是__bridge_transfer的宏定义——你去看系统头文件就能发现,它的定义就是:

#define CFBridgingRelease(X) ((__bridge_transfer id)(X))

所以两者从功能上是100%等价的,不存在任何逻辑差异。

那你看到的不同结果是怎么来的?问题出在这句代码:

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

当你调用CFBridgingRelease(cfObject)或者__bridge_transfer时,已经把cfObject的所有权转移给了OC对象obj,此时ARC完全有权立即释放原CF对象,或者让cfObject变成野指针。这时候再去调用CFGetRetainCount(cfObject)属于未定义行为,返回的数值完全不可信,可能因为编译器优化、ARC的自动操作而随机变化,根本不能用来判断两者的差异。

正确的测试姿势

转移所有权后,别再碰原来的CF指针了,把注意力放在OC对象obj上。比如改成这样测试:

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
        CFMutableArrayRef cfObject = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); 
        printf("CF retain count before transfer = %ld\n", CFGetRetainCount(cfObject)); // 这里应该是1
        
        id obj = CFBridgingRelease(cfObject); 
        // 改用OC对象的retainCount(虽然ARC下这个值也仅供参考,但至少不会操作野指针)
        printf("OC retain count after transfer = %ld\n", [obj retainCount]); 
        
        NSLog(@"class=%@", obj); 
    }
}

总结

CFBridgingRelease和__bridge_transfer没有任何功能差异,你看到的不同结果只是因为操作了已经失效的CF指针导致的随机现象。在ARC下,一旦完成所有权转移,就应该彻底抛弃原CF指针,只使用转换后的OC对象。

内容的提问来源于stack exchange,提问作者EricXuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:55:46