Ios Objective-C类作为C指针类型

Ios Objective-C类作为C指针类型,ios,objective-c,c,automatic-ref-counting,Ios,Objective C,C,Automatic Ref Counting,clangbuiltin函数“\uu builtin\u NSStringMakeConstantString”返回常量NSConstantString* 这不是一个客观的可保留对象 我想用我自己的函数替换这个函数,但似乎没有办法在Objective-C++中将NSConstantString*声明为非Objective-C指针(您可以在Objective-C中使用struct NSConstantString*)。我确信,此函数返回NSConstantString,因为以下两行输出了PK16N

clangbuiltin函数“\uu builtin\u NSStringMakeConstantString”
返回常量
NSConstantString*

这不是一个客观的可保留对象

我想用我自己的函数替换这个函数,但似乎没有办法在Objective-C++中将
NSConstantString*声明为非Objective-C指针(您可以在Objective-C中使用
struct NSConstantString*
)。我确信,此函数返回
NSConstantString
,因为以下两行输出了
PK16NSConstantString

printf("%s\n", typeid(__builtin___NSStringMakeConstantString("foo")).name());
printf("%s\n", typeid(const NSConstantString*).name());
每当我尝试执行以下代码时,就会出现错误“无法使用类型为“const NSConstantString*”的右值初始化类型为“const NSConstantString*”的变量”:


如果我添加桥转换,一切正常,因此这意味着NSConstantString*作为“原始”Objective-C指针返回,但我必须创建一个返回与“\uu builtin\u NSStringMakeConstantString”完全相同的结果的函数,所以我没有选择使用\uu桥

每当我尝试从函数返回const NSConstantString*时,它总是作为Objective-C可保留指针返回,并且似乎没有办法将其声明为C指针,除非:

typedef typeof __builtin___NSStringMakeConstantString("") rawNSConstnatStringPtr;

所以问题是:有没有一种方法可以声明指向NSConstantString*的不可恢复指针(不使用typeof)?

您认为
\u builtin\u NSStringMakeConstant
返回
NSConstantString
,因为编译器在欺骗您

我建议您查看一下clang源代码:

然后搜索源代码:
git grep\uuuuu builtin\uuuuu NSStringMakeConstantString
。您会发现它在
include/clang/Basic/Builtins.def
中的定义如下:

BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
第二个参数是函数签名,文件顶部的注释解释了它的含义。
FC*
部分是返回类型,表示“常量CFString const pointer”。这是有道理的,因为
CFString
NSString
是免费桥接的

但这没有意义,因为错误消息特别提到了
NSConstantString
。因此,
git grep-w NSConstantString
来看看这是从哪里来的。您最终会在
lib/ast/ASTContext.cpp
中找到方法
ASTContext::getCFConstantStringType
。此方法使用标识符
NSConstantString
创建结构类型声明,但它从不将声明添加到任何范围(它不调用
PushOnScopeChains
AddDecl
)。因此,
NSConstantString
标识符可以出现在诊断中,但您不能在源代码中按名称访问类型。就编译器而言,
NSString.h
中声明的
NSConstantString
类型与此合成类型无关

无论如何,重要的问题是为什么要覆盖
\uuuuuuuu内置的
,您没有说。如果是因为您想使用自己的常量字符串类,那么您的做法是错误的

我认为您不能重写该函数,因为它内置于编译器中。如果要更改编译器源代码的含义,则需要修改它

另外,我不认为编译器实际使用该函数来创建Objective-C字符串文本。运行
git grep\uuuu builtin\uuuu NSStringMakeConstantString
不会出现编译器生成对其调用的任何位置。编译器在
lib/Parse/ParseObjc.cpp
lib/Sema/SemaExprObjC.cpp
中处理
@“string”
语法(在这两个文件中查找名为
ParseObjCStringLiteral
)。编译器按名称查找
NSConstantString
类型(这意味着它应该从
NSString.h
头文件中获取该类型),并使用该类型创建
ObjCStringLiteral
的实例


您应该能够使用
-fconstant-string-class
命令行标志让它为常量字符串类型查找不同的类(而不是
NSConstantString
),但我不知道这有多好。这意味着它可能不起作用。即使它能工作,我想你也只能使用与
NSConstantString
相同的内存布局,在这种情况下,为什么还要麻烦使用不同的类呢?

你试过“bridge”吗?我没有选择使用“bridge”,我需要创建一个“builtin\uu\NSStringMakeConstantString”函数的精确副本,但我找不到返回“raw”的方法C指向NSConstantString的指针。
NSString*str=(\uu桥NSString*)a桥接器不会修改指针…或者不要使用arc并忘记桥接器谢谢!我必须使用NSConstantString,因为我正在转换客户机的代码(将“_builtin__NSStringMakeConstantString”替换为一个函数,该函数在内存中清除模糊字符串),并且在转换后它必须保持不变。如果他在模板中使用它或将其用作函数的参数,则结果类型必须保持不变。如果没有其他选项,我想我必须坚持使用“typeof uuuu builtin uuuuu NSStringMakeConstantString(“”)”。
BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")