5

如果我理解正确,我们可以将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 可保留指针类型”有点怀疑。描述; 尤其是关于(possibly qualifier)(possible qualifier)的意图。我们可以将哪些指针类型归类为“C 可保留指针类型”

另外,它实际上是否意味着“系统全局变量”语句中的系统全局变量?


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

如果一个表达式是已知的,则它与保留无关:

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

如果强制转换操作数已知为 unretained 或已知 retain-agnostic,则转换被视为 __bridge cast

7.8. C 可保留指针类型

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

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

4

2 回答 2

2

似乎 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,然后清理/构建项目,但它没有禁用这些常量的隐式桥接。

于 2012-11-30T20:37:41.070 回答
1

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

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

CF_IMPLICIT_BRIDGING_ENABLED

在接近尾声时你会发现:

CF_IMPLICIT_BRIDGING_DISABLED

这些宏被定义CFBase.h为开始和结束clang arc_cf_code_audited编译指示,它被定义了。

于 2012-11-30T21:09:08.823 回答