对于CF类型,带有__attribute __((NSObject))的强大的@property不会保留 [英] strong @property with __attribute__((NSObject)) for a CF type doesn't retain

查看:129
本文介绍了对于CF类型,带有__attribute __((NSObject))的强大的@property不会保留的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:此问题自Xcode 4.6起已修复!

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

This technique now works as intended again. However, make sure to read the notes at the top of Rob Napier's excellent answer before you use it in your code.

原始帖子

(ARC,Xcode 4.3.1,iOS 5.1)

(ARC, Xcode 4.3.1, iOS 5.1)

我有一个强大的CF类型属性(CGImage) )我希望ARC使用 __ attribute __((NSObject))自动管理(就像在合成的setter中保留和释放一样,并且它在nil'ed in dealloc),但它不起作用:当我分配属性时,不保留对象。

I have a strong property of a CF type (CGImage) that I want to be automatically managed by ARC using __attribute__((NSObject)) (as in having retain & release in the synthesized setter, and it being nil'ed in dealloc), but it doesn't work: the object is not retained when I assign the property.

重现的最小例子:

@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。未升级(或知道如何更改编译器)的人可以确认吗?

Now the strange thing is that (although I'm not sure of this) I think it worked properly before I updated to iOS 5.1 & Xcode 4.3.1 (from iOS 5 & Xcode 4.2), and with it switched from gdb to lldb. Can someone who hasn't upgraded (or knows how to change back the compiler) perhaps confirm?

推荐答案

EDIT2( 2013年3月)对于那些对此技术感兴趣的人,仅供参考, ARC文档for clang 包含以下注释:

EDIT2 (Mar 2013) FYI for those interested in this technique, ARC documentation for clang includes the following note:


使用 __ attribute __((NSObject))不推荐使用typedef。如果绝对有必要使用此属性,请非常明确地使用typedef,并且不要假设它将由 __ typeof 和C ++模板参数替换等语言功能保留。

The use of __attribute__((NSObject)) typedefs is not recommended. If it’s absolutely necessary to use this attribute, be very explicit about using the typedef, and do not assume that it will be preserved by language features like __typeof and C++ template argument substitution.

基本原理

任何编译器操作偶然地从中删除类型糖 type将生成一个没有属性的类型,这可能会导致意外行为。

Any compiler operation which incidentally strips type "sugar" from a type will yield a type without the attribute, which may result in unexpected behavior.






编辑以下内容很有趣,但可能无关紧要。这是一个错误,你应该打开一个雷达。正如@lnafziger所指出的那样,这是合法的,应该受到尊重。这个错误是当你包含 nonatomic 时它没有被尊重。如果你删除 nonatomic ,那么它可以工作。 nonatomic 定义中没有任何内容表明这是设计使然。


EDIT The below is interesting, but probably irrelevant. This is a bug and you should open a radar. As noted by @lnafziger, this is legal and is supposed to be honored. The bug is that it is not honored when you include nonatomic. If you remove nonatomic, then it works. Nothing in the nonatomic definition suggests that this is by design.

这有点聪明,但我想我明白为什么它不起作用。您可以通过生成汇编程序并注意 setStr:不调用 objc_storeStrong()。它做了一个简单的赋值。

This is kind of clever, but I think I see why it isn't working. You can confirm, btw, that it isn't working by generating the assembler and noting that setStr: does not call objc_storeStrong(). It does a simple assign.

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

The problem is that your property definition does not conform to the definition of a retainable object pointer (emphasis added):


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

A retainable object pointer (or retainable pointer) is a value of a retainable object pointer type (retainable type). There are three kinds of retainable object pointer types:


  • 块指针(通过应用插入符号(^)声明符sigil形成) a
    函数类型)

  • Objective-C对象指针(id,Class,NSFoo *等)

  • typedef 标有__attribute __((NSObject))

  • block pointers (formed by applying the caret (^) declarator sigil to a function type)
  • Objective-C object pointers (id, Class, NSFoo*, etc.)
  • typedefs marked with __attribute__((NSObject))

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

Did you create a typedef as specified? No you did not. OK, so how would we do this?

typedef __attribute__((NSObject)) CFStringRef MYStringRef;

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

... the rest of your code ...

按照我的预期,这将打印1然后打印2。因为未指明的原因让我感到害怕,但是看看汇编输出,一切似乎都很好,我想不出任何具体的问题或违规行为。

This will print "1" and then "2" as I assume you expect. Scares me for unspecified reasons, but looking at the assembler output, everything seems fine and I can't think of any specific problem or violation here.

你可能有理由为此打开雷达。即使记录在案,也不至于将typedef处理为与指定类型相同的事实令人惊讶。

You could be justified in opening a radar for this. The fact that a typedef is not treated the same as a specified type is surprising at least, even if documented.

编辑:注意@ lnafziger's来自 ObjC编程语言的评论,ARC规范/实现中肯定存在错误或链接文档中存在错误,因此应修复其中一个错误。

Noting @lnafziger's comment from the ObjC Programming Language, there is definitely either an error in the ARC spec/implementation or an error in the linked document, so one of them should be fixed.

这篇关于对于CF类型,带有__attribute __((NSObject))的强大的@property不会保留的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆