更新:此问题自Xcode 4.6起已修复!
此技术现在再次按预期工作。但是,在您的代码中使用之前,请务必阅读Rob Napier优秀答案顶部的注释。
原始帖子
(ARC,Xcode 4.3.1,iOS 5.1)
我有一个CF类型(CGImage)的强大属性,我希望ARC使用__attribute__((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。未升级(或知道如何更改编译器)的人可能会确认吗?
答案 0 :(得分:33)
EDIT2(2013年3月)对于对此技术感兴趣的人,ARC documentation for clang包含以下注释:
不建议使用
__attribute__((NSObject))
typedef。如果绝对有必要使用此属性,请非常明确地使用typedef,并且不要假设它将由__typeof
和C ++模板参数替换等语言功能保留。<强>原理强>
任何偶然从类型中删除类型“sugar”的编译器操作都会产生一个没有属性的类型,这可能会导致意外行为。
编辑以下内容很有趣,但可能无关紧要。这是一个错误,你应该打开一个雷达。正如@lnafziger所指出的那样,这是合法的,应该受到尊重。问题在于,当您加入nonatomic
时,它不会受到尊重。如果您删除nonatomic
,那么它可以正常运行。 nonatomic
定义中没有任何内容表明这是设计的。
这有点聪明,但我想我明白为什么它不起作用。您可以通过生成汇编程序并注意setStr:
不调用objc_storeStrong()
来确认它无法正常工作。它做了一个简单的分配。
问题是你的属性定义不符合可保留对象指针的定义(强调添加):
可保留对象指针(或可保留指针)是a的值 可保留对象指针类型(可保留类型)。有三种 各种可保留的对象指针类型:
- 块指针(通过将插入符号(^)声明符sigil应用于a 功能类型)
- Objective-C对象指针(id,Class,NSFoo *等)
标有__attribute __((NSObject))的- typedefs
您是否按指定创建了typedef?不,你没有。好的,那我们怎么做呢?
typedef __attribute__((NSObject)) CFStringRef MYStringRef;
@interface TestClass : NSObject
@property (nonatomic, strong) MYStringRef str;
@end
... the rest of your code ...
这将打印“1”,然后打印“2”,因为我认为你期望。因为未指明的原因让我害怕,但看着汇编输出,一切似乎都很好,我不能想到任何具体问题或违规行为。
你可能有理由为此打开雷达。即使记录,typedef的处理方式与指定类型不同,这一事实至少令人惊讶。
编辑:注意来自ObjC Programming Language的@ lnafziger的评论,无论是ARC规范/实现中的错误还是链接文档中的错误,因此其中一个应该是固定的。