objective-c - 具有 __attribute__((NSObject)) 的 CF 类型的强@property 不保留

标签 objective-c ios automatic-ref-counting core-foundation

更新:此问题已从 Xcode 4.6 开始修复!

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

原帖

(ARC,Xcode 4.3.1,iOS 5.1)

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

一个最小的重现示例:

@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 documentation for clang包括以下说明:

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.


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


这有点聪明,但我想我明白为什么它不起作用。顺便说一句,您可以通过生成汇编器并注意 setStr: 不调用 objc_storeStrong() 来确认它没有工作。它执行简单的分配。

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

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

您是否按规定创建了 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 规范/实现中肯定存在错误,或者链接文档中存在错误,因此应该修复其中一个。

关于objective-c - 具有 __attribute__((NSObject)) 的 CF 类型的强@property 不保留,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9684972/

相关文章:

ios - 将图像存储到 iPhone 有延迟

iphone - 如何将混响滤波器或任何其他声音效果应用于 .wav 声音文件?

ios - UILabel 切断符号

iOS 使用谷歌 MaterialComponents?

iOS ARC(?) 窃取了我的搜索栏

objective-c - 为什么当我的应用程序处于后台时,关闭模拟器会使我的应用程序收到SIGTERM?

objective-c - 我将如何实现委托(delegate)将值从子 swift 类传递到父 Objective-C 类?

ios - 如何更改 UILabel.text 属性以遍历字符串数组而不是对索引进行硬编码

ios - 管理 CGImageRef 内存的规则?

objective-c - 如何在启用 ARC 的情况下正确使用 CFURLCreateCopyAppendingPathComponent?