【问题标题】:ARC - implicit bridgingARC - 隐式桥接
【发布时间】:2012-11-17 11:30:21
【问题描述】:

如果我理解正确,我们可以将 void * 归类为 “C 可保留指针类型”。 因此,将其分配给 Objective-C 对象将被隐式桥接。但是,编译器会引发需要显式桥接的错误。

   const void * somePtr = (void *)0x12345678;
   - (void)someMethod:(id)sender
   {
        NSObject *obj = (NSObject *)somePtr;
   }

另外,我检查了空指针常量,它编译时没有显式桥接。

    NSObject *obj = (void *)0;

我正在使用 XCode 4.5(Clang 4.1 (tags/Apple/clang-421.11.66) (基于 LLVM 3.1svn))。


问题: 我知道将一些任意/不相关的指针分配给 NSObject 有点奇怪,但我想确保我是否正确理解了规则。我有点怀疑“C 可保留指针类型”。 描述;特别是关于(可能有资格)(可能有资格)的意图。我们可以将哪些指针类型归类为“C 可保留指针类型”

另外,它实际上是指“系统全局变量”语句来自系统的全局变量吗?


3.3.2.转换为具有已知语义的可保留对象指针类型的表达式 [开始于 Apple 4.0,LLVM 3.1]

一个表达式是已知的保留不可知,如果它是:

  • Objective-C 字符串文字,
  • C 可保留指针类型的 const 系统全局变量加载,
  • 或空指针常量。

如果转换操作数已知为未保留或已知保留不可知,则转换被视为 __bridge 转换

7.8。 C 可保留指针类型

如果一个类型是指向 (可能限定) void 的指针或指向 (可能限定符) 结构或类类型的指针,则该类型是 C 可保留指针类型。

http://clang.llvm.org/docs/AutomaticReferenceCounting.html

【问题讨论】:

    标签: objective-c automatic-ref-counting


    【解决方案1】:

    似乎 const 系统全局变量实际上不需要显式桥接。 即 kCFBooleanTrue(CFBoolean 实例)、kCFNumberNaN 或 kABPersonPhoneMobileLabel。

    NSObject *obj = (NSObject *)kCFBooleanTrue;
    

    请注意,CFBoolean 不是免费桥接的,但编译器仍可以隐式桥接它。 我定义了全局常量,但无法使用隐式桥接编译它们。 所以,我想知道编译器如何确定变量是否来自系统? (或者可能是检查类型是否来自 CoreFoundation.framework 这不是一个简洁的解决方案......)

    --- 编辑---

    参考 rob mayoff 的回答,我尝试了隐式桥接,但它仍然不起作用。可能有一个编译器标志来确定该文件是核心基础文件。

    NSObject *obj = (NSObject *)myGlobal;
    

    “mytest.h”文件

    #ifndef mytest_h
    #define mytest_h
    
    #pragma clang arc_cf_code_audited begin
    
    typedef const struct MyStruct * MyStructPtr;
    
    CF_EXPORT
    const MyStructPtr myGlobal;
    
    #pragma clang arc_cf_code_audited end
    #endif
    

    “mytest.c”文件

    #include "mytest.h"
    
    struct MyStruct {
        int a;
    };
    
    static struct MyStruct __myglobal = { 123 };
    const MyStructPtr myGlobal = &__myglobal;
    

    --- 编辑---

    我还修改了 CoreFoundation.framework 中的 CFNumber.h 头文件并删除了 CF_IMPLICIT_BRIDGING_ENABLED/CF_IMPLICIT_BRIDGING_DISABLED,然后清理/构建项目,但它并未禁用这些常量的隐式桥接。

    【讨论】:

      【解决方案2】:

      虽然您链接的文档中没有说明,但我相信“const 系统全局变量”的“系统”部分意味着该变量是在 pragma clang arc_cf_code_audited 生效时定义的。

      看看CFNumber.h的顶部,你会发现:

      CF_IMPLICIT_BRIDGING_ENABLED
      

      在接近尾声时你会发现:

      CF_IMPLICIT_BRIDGING_DISABLED
      

      这些宏在CFBase.h 中定义,用于开始和结束clang arc_cf_code_audited pragma,它已定义。

      【讨论】:

      • “CF_IMPLICIT_BRIDGING_ENABLED”究竟是如何工作的?我们可以在自己的 API 中使用它们吗?
      • 由于CF_IMPLICIT_BRIDGING_ENABLED 只是_Pragma("clang arc_cf_code_audited begin") 的宏,它通过启用特定于clang 的功能来工作。如果您想了解更多信息,则必须查看 clang 源代码。如果你的 API 定义了自己的CFType“子类”,那么在你自己的 API 中使用才有意义。据我所知,Apple 尚未发布用于创建 CFType 子类的 API。
      猜你喜欢
      • 1970-01-01
      • 2012-03-17
      • 2011-10-12
      • 2011-10-25
      • 2023-03-17
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多