gpt4 book ai didi

objective-c - 我应该使用哪个 __bridge 免费桥接来将 Objective-C 便捷构造函数转换为 C ref?

转载 作者:太空狗 更新时间:2023-10-30 04:02:07 25 4
gpt4 key购买 nike

我正在尝试将手动保留发布代码转换为 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 类型的例子,他写道:

By using __bridge_retained, we can tell ARC to transfer ownership out of the system and into our hands. Since ownership is transferred, we're now responsible for releasing the object when done with it, just like with any other CF code

...否则,如果我们只使用 __bridge,ARC 将不会努力保留我们 CFTypeRef 帐户上的内存。

所以这是我认为最明智的做法:

mSourceText.font = (__bridge_retained CFTypeRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];
... // At some later point
CFRelease(mSourceText.font);

现在,如果那是正确的,我仍然不清楚何时可以确定它是安全的,但如果我从未释放,那至少只是一个小的内存泄漏,对吧?

总而言之,我的实际问题是:

  1. 我建议的代码是否正确?
  2. 我应该在哪里 CFRelease 这个对象?在 SourceItemCell 的 dealloc 函数中?

这就是为什么我认为相关问题没有回答我的问题:

  1. Must I use __bridge or __bridge_retained if I'm bridging an autoreleased object to Core Foundation?我不确定将 Objective-C 便利构造函数显式保存到上一行的 Objective-C 变量是否重要。此外,批准的答案说只使用 __bridge_retained “如果你想管理 C 对象的生命周期”,我认为这是错误的......我觉得很多人都在使用 __bridge_retained 因为他们 自己管理生命周期。
  2. Where and how to __bridge批准的答案具有有用的摘要,但侧重于未保留的示例。

附言。请不要评判我,因为我使用的是 Helvetica...:)

编辑:

当我使用 __bridge_retained 并进行静态分析时,我得到了这样的提示:

Static analyzer complaint

“属性返回一个保留计数为 +0 的 Core Foundation 对象。调用者此时不拥有的对象的引用计数减少不正确。”

(我认为 mDelegate 和 IS_ARC 行与此问题无关。)

所以有些事情我从根本上没有正确理解......

最佳答案

首先,我想知道原始MRR代码是否正确。根据文档,您不能将 UIFont 对象分配给 CATextLayerfont 属性,但可以将 CTFontRef,或 CGFontRef。像这样的东西应该可以正常工作:

 CGFontRef font = CGFontCreateWithFontName(CFSTR("HelveticaNeue"));
mSourceText.font = font;
CGRelease(font);
mSourceText.fontSize = 12.0;

为了回答您关于桥接的问题,我们假设将 UIFont * 转换为 CGFontRef 是正确的(我很确定不是!)。然后你会使用__bridge:

 mSourceText.font = (__bridge CGFontRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];

原因是 mSourceText 中的 CATextLayer 对象将保留字体本身,因此我们不需要这样做。

如果我们将 CGFontRef 存储在两者之间,我们必须小心。像这样的代码是危险的:

CGFontRef fontRef = (__bridge CGFontRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];
mSourceText.font = fontRef;

ARC 可能会在第一条和第二条语句之间释放 UIFont 对象,这样 fontRef 指针就会指向一个释放的对象。如果我们想在两个语句中编写代码,我们必须保留对象,使其存活足够长的时间以便分配,然后再释放它:

CGFontRef fontRef = (__bridge_retained CGFontRef)[UIFont fontWithName:@"HelveticaNeue" size:12.0];
mSourceText.font = fontRef;
CFRelease(fontRef);

关于objective-c - 我应该使用哪个 __bridge 免费桥接来将 Objective-C 便捷构造函数转换为 C ref?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16614040/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com