如果我理解正确,我们可以将 void * 归类为“C可保留指针类型”。 因此,将它隐式桥接到Objective-C对象。但是,编译器会引发需要显式桥接的错误。
const void * somePtr = (void *)0x12345678;
- (void)someMethod:(id)sender
{
NSObject *obj = (NSObject *)somePtr;
}
另外,我检查了空指针常量,它编译时没有明确的桥接。
NSObject *obj = (void *)0;
我正在使用XCode 4.5(标签/ Apple / clang-421.11.66 )(基于 LLVM 3.1svn )。
问题: 我知道向NSObject分配一些任意/不相关的指针有点奇怪,但我想确定是否正确理解规则。我对“C可保持指针类型”有点怀疑。描述;尤其是关于(可能合格)和(可能是限定词)的意图。我们可以将哪些指针类型归类为“C可保留指针类型”?
此外,它实际上是指“系统全局变量”声明中来自系统的全局变量吗?
3.3.2。转换为具有已知语义的表达式的可保留对象指针类型 [从Apple 4.0开始,LLVM 3.1]
表达式已知保留不可知如果是:
- Objective-C字符串文字,
- 来自const系统全局变量 C可保留指针类型的负载,
- 或空指针常量。
如果演员操作数已知未记录或已知保留不可知,则转换视为__bridge演员。
7.8。 C可保留指针类型
如果类型是指向(可能合格) void的指针或指向(可能是限定符)结构或类类型的指针,则类型是C可保留指针类型。
答案 0 :(得分:2)
似乎const系统全局变量实际上不需要显式桥接。 即kCFBooleanTrue(CFBoolean instance),kCFNumberNaN或kABPersonPhoneMobileLabel。
NSObject *obj = (NSObject *)kCFBooleanTrue;
请注意,CFBoolean不是免费的桥接,但它仍然可以被编译器隐式桥接。 我定义了全局常量,但无法使用隐式桥接编译它们。 所以,我想知道编译器如何确定变量是否来自系统? (或者可能是检查类型是否来自CoreFoundation.framework,这不是一个简洁的解决方案......)
---编辑---
参考rob mayoff的回答,我尝试了隐式桥接,但它仍然无效。可能有一个编译器标志将文件确定为Core Foundation文件。
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 ,然后清理/构建项目,但它没有禁用这些常量的隐式桥接。
答案 1 :(得分:2)
虽然在您链接的文档中没有说明,但我认为“const
系统全局变量”的“系统”部分意味着变量是在pragma clang arc_cf_code_audited
生效时定义的。 / p>
查看CFNumber.h
的顶部,您会发现:
CF_IMPLICIT_BRIDGING_ENABLED
接近结束时你会发现:
CF_IMPLICIT_BRIDGING_DISABLED
这些宏在CFBase.h
中定义,以开始和结束clang arc_cf_code_audited
编译指示,它已定义。