我正在尝试将手动保留发布代码转换为 ARC。
当我有一个 Objective-C 便利构造函数,其返回指针值存储在 CFTypeRef 中时,我正在努力找出免费桥接的正确方法。
现有代码,使用 MRR:
@interface SourceItemCell UITableViewCell
{
CATextLayer *mSourceText;
}
@implementation SourceItemCell
- (id)init
{
self = [super init];
mSourceText = [CATextLayer layer];
// key line I'm wondering about:
mSourceText.font = [UIFont fontWithName:@"HelveticaNeue" size:12.0];
[[self contentView].layer addSublayer:mSourceText];
return self;
}
为了让您不必查找文档,CATextLayer 的字体属性是 CFTypeRef 类型。
看来我的选择是:
mSourceText.font = (__bridge CFTypeRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];
或者:
mSourceText.font = (__bridge_transfer CFTypeRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];
或者:
mSourceText.font = (__bridge_retained CFTypeRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];
这是我的想法。我发现的最清晰的免费桥接指南是http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html。有一个从 Objective-C 类型转换为 C 类型的类似示例,他写道:
通过使用 __bridge_retained,我们可以告诉 ARC 将所有权从系统转移到我们手中。由于所有权已转移,我们现在负责在完成对象后释放它,就像任何其他 CF 代码一样
...否则,如果我们只使用 __bridge,ARC 将不会做任何努力来保留我们 CFTypeRef 帐户上的内存。
所以这是我认为最明智的方法:
mSourceText.font = (__bridge_retained CFTypeRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];
... // At some later point
CFRelease(mSourceText.font);
现在,如果那是正确的,我仍然不清楚何时可以确定释放它是安全的,但如果我从未释放,它至少只是一个小的内存泄漏,对吧?
总之,我的实际问题是:
- 我建议的代码正确吗?
- 我应该在哪里 CFRelease 这个对象?在 SourceItemCell 的 dealloc 函数中?
这就是为什么我认为相关问题没有回答我的问题的原因:
- 如果我将自动释放的对象桥接到 Core Foundation,我必须使用 __bridge 或 __bridge_retained 吗?我不确定将 Objective-C 便利构造函数显式保存到上一行的 Objective-C 变量是否重要。此外,批准的答案说只使用 __bridge_retained “如果你想管理 C 对象的生命周期”,我认为这是错误的......我感觉很多人都在使用 __bridge_retained 因为他们必须自己管理生命周期.
- Where and how to __bridge Approved answer有有用的总结,但侧重于非保留示例。
PS。请不要因为我使用 Helvetica 就评判我... :)
编辑:
当我使用 __bridge_retained 并进行静态分析器时,我收到以下投诉:
“属性返回一个具有 +0 保留计数的核心基础对象。调用者此时不拥有的对象的引用计数不正确递减。”
(我相信 mDelegate 和 IS_ARC 行与这个问题无关。)
所以有些东西我基本上没有正确理解......