Objective c CF类型为'的带有uuu属性uuu((NSObject))的强@property;留不住

Objective c CF类型为'的带有uuu属性uuu((NSObject))的强@property;留不住,objective-c,ios,automatic-ref-counting,core-foundation,Objective C,Ios,Automatic Ref Counting,Core Foundation,更新:从Xcode 4.6开始,此问题已得到修复 这项技术现在又按预期工作了。但是,在代码中使用Rob Napier的优秀答案之前,请务必阅读其顶部的注释 原创帖子 (ARC、Xcode 4.3.1、iOS 5.1) 我有一个CF类型(CGImage)的强属性,我希望ARC使用\uuuuu attribute\uuuuuu((NSObject))自动管理该属性(就像在合成setter中保留和释放一样,在dealloc中为零),但它不起作用:分配属性时对象不会被保留 复制的一个最小示例: @int

更新:从Xcode 4.6开始,此问题已得到修复

这项技术现在又按预期工作了。但是,在代码中使用Rob Napier的优秀答案之前,请务必阅读其顶部的注释

原创帖子

(ARC、Xcode 4.3.1、iOS 5.1)

我有一个CF类型(CGImage)的强属性,我希望ARC使用
\uuuuu attribute\uuuuuu((NSObject))
自动管理该属性(就像在合成setter中保留和释放一样,在dealloc中为零),但它不起作用:分配属性时对象不会被保留

复制的一个最小示例:

@interface TestClass : NSObject
@property (nonatomic, strong) __attribute__((NSObject)) CFStringRef str;
@end

// ...In some function
CFStringRef str = (__bridge CFStringRef)[NSString stringWithFormat:@"%g", 2.5];
NSLog(@"%ld", CFGetRetainCount(str));
TestClass *obj = [[TestClass alloc] init];
obj.str = str;
NSLog(@"%ld", CFGetRetainCount(str));
打印“1”两次

现在奇怪的是(尽管我不确定这一点),我认为在我升级到iOS 5.1和Xcode 4.3.1(从iOS 5和Xcode 4.2)之前,它工作正常,并且从gdb切换到lldb。没有升级(或知道如何更改回编译器)的人可以确认吗?

EDIT2(2013年3月)FYI对于那些对此技术感兴趣的人,包括以下注释:

不建议使用
\uuuu属性(NSObject))
typedefs。如果使用这个属性是绝对必要的,那么对于使用Type,非常明确,不要假设它将被语言特性保存,例如“代码”、“X类型”< /> >和C++模板参数替换。

基本原理

任何从类型中意外删除类型“sugar”的编译器操作都将生成一个没有该属性的类型,这可能会导致意外行为


编辑下面的内容很有趣,但可能不相关。这是一个错误,你应该打开雷达。正如@lnafziger所指出的,这是合法的,应该得到尊重。错误在于,如果包含
非原子的
,则不尊重它。如果删除非原子的,则它可以工作。
非原子定义中没有任何东西表明这是故意的


这有点聪明,但我想我明白为什么它不起作用了。顺便说一句,您可以通过生成汇编程序并注意
setStr:
没有调用
objc\u storeStrong()
来确认它不起作用。它做一个简单的赋值

问题是您的属性定义不符合可保留对象指针的定义(添加了强调):

可保留对象指针(或可保留指针)是 可保留对象指针类型(可保留类型)。有三个 可保留对象指针类型的种类:

  • 块指针(通过将插入符号(^)声明符sigil应用于 功能类型)
  • Objective-C对象指针(id、类、NSFoo*等)
  • typedefs用_属性_((NSObject))标记
您是否按照指定创建了typedef?不,你没有。好的,那我们怎么做呢

typedef __attribute__((NSObject)) CFStringRef MYStringRef;

@interface TestClass : NSObject
@property (nonatomic, strong) MYStringRef str;
@end

... the rest of your code ...
这将打印“1”,然后是“2”,正如我假设您所期望的那样。由于未指明的原因使我感到害怕,但从汇编程序的输出来看,一切似乎都很好,我想不出有什么具体的问题或违规

你有理由为此打开雷达。typedef未被视为与指定类型相同的事实至少令人惊讶,即使有文档记录


编辑:注意@lnafziger在中的评论,ARC规范/实现中肯定存在错误,或者链接文档中存在错误,因此其中一个应该修复。

一个解决方案就是使用
NSString*
属性,在分配时使用
\u bridge
cast。我没有从希望你得到什么中得到任何东西。不幸的是,这只是一个复制的示例,在我实际使用的代码中,我有一个CGImage。我会编辑这篇文章。是的,这是真的,而且ARC的价格很低,即使在Mac上:似乎在OSX10.8.2下的Xcode4.6中已经被修正了。编译器生成对
objc\u setProperty\u nonatomic
的调用,该调用将
objc\u按预期保留新值。有人能确认iOS 6.1吗?打开了雷达。很高兴你能找到它工作的条件。顺便说一句,如果你确实打开了雷达,请在这里张贴#。