strong @property with __attribute__((NSObject)) for a CF type doesn't retain

匆匆过客 提交于 2019-12-02 15:55:16

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

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.

Rationale

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


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.


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:

  • 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))

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 ...

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.

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.

EDIT: 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!