用__attribute __((NSObject))为CFtypes强的@property不保留

更新:这个问题已经修复Xcode 4.6!

这项技术现在再次按预期工作。 但是,在你使用代码之前,一定要阅读Rob Napier最佳答案的注释。

原来的post

(ARC,Xcode 4.3.1,iOS 5.1)

我有一个CFtypes的强大的属性(CGImage),我想通过ARC使用__attribute__((NSObject))自动pipe理(如在保留和释放在合成的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月)对于那些对这项技术感兴趣的人员, 供叮当使用的ARC文档包括以下说明:

不推荐使用__attribute__((NSObject)) typedefs。 如果使用这个属性是绝对必要的,那么应该非常明确的使用typedef,而不要以为它会被诸如__typeof和C ++模板参数replace之类的语言特性所保留。

合理

任何偶然从types中去除types“糖”的编译器操作都会产生一个没有属性的types,这可能会导致意外的行为。


编辑下面是有趣的,但可能无关紧要。 这是一个错误,你应该打开雷达。 正如@lnafziger所指出的,这是合法的,应该受到尊重。 这个错误是,当你包含nonatomic时,它是不被尊重的。 如果你删除nonatomic ,那么它的作品。 nonatomic定义中的任何内容都暗示这是devise的。


这很聪明,但我想我明白为什么它不工作。 您可以通过生成汇编程序并注意到setStr:不会调用objc_storeStrong() 。 它做了一个简单的分配。

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

可保留对象指针(或可保留指针)是可保留对象指针types(可保留types)的值。 有三种可保留的对象指针types:

  • 块指针(通过将脱字号(^)声明符sigil应用于函数types而形成)
  • Objective-C对象指针(id,Class,NSFoo *等)
  • 用__attribute __((NSObject))标记的typedefs

你是否按照指定创build了一个typedef? 不,你没有。 好的,那我们怎么做呢?

 typedef __attribute__((NSObject)) CFStringRef MYStringRef; @interface TestClass : NSObject @property (nonatomic, strong) MYStringRef str; @end ... the rest of your code ... 

这将打印“1”,然后“2”,我假设你的预期。 害怕我不明确的原因,但看看汇编输出,一切似乎都很好,我想不出任何具体的问题或违反这里。

你可能有理由为此打开雷达。 至less,即使有文档logging,typedef的处理方式与指定types不同的事实也是令人惊讶的。

编辑:从ObjC编程语言中注意@ lnafziger的评论,在ARC规范/实现中肯定有错误,或者在链接文档中有错误,所以应该修正其中的一个。