从 C++ 调用 Obj-C 消息时如何防止自动保留/释放?
我有一些这样的代码:
@interface MyTimer : NSObject
- (int)getValue;
@end
@interface TimerHolder : NSObject {
ExternalControl* m_externalControl;
}
@property (retain, nonatomic) MyTimer* timer;
@end
class ExternalControl {
__unsafe_unretained TimerHolder* m_holder;
public:
ExternalControl(TimerHolder* holder) : m_holder(holder);
int getTimer() { return [m_holder.timer getValue] };
};
方法 ExternalControl::getTimer()
被非常频繁地调用。在分析过程中,我注意到在调用 getTimer()
期间,obc-j 还调用 objc_retain
和 objc_release
(大概是在 m_holder 或 m_holder 上)。计时器),这最终会占用大量时间!删除 __unsafe_unretained 并没有什么区别。
通过构造,我知道每当调用 ExternalControl::getTimer()
时,m_holder 及其计时器将在调用期间保持活动状态,因此我认为保留/释放是不必要的。
有什么办法可以防止他们被调用吗?
我正在使用带有 iOS 5 SDK 的 XCode 4.2,并启用了 ARC。 ARC 负责吗?删除它会删除保留/释放吗? (我不想花时间在没有 ARC 的情况下重新创建一个项目来测试这个,然后再和朋友们确认一下!)
I've got some code like this:
@interface MyTimer : NSObject
- (int)getValue;
@end
@interface TimerHolder : NSObject {
ExternalControl* m_externalControl;
}
@property (retain, nonatomic) MyTimer* timer;
@end
class ExternalControl {
__unsafe_unretained TimerHolder* m_holder;
public:
ExternalControl(TimerHolder* holder) : m_holder(holder);
int getTimer() { return [m_holder.timer getValue] };
};
The method ExternalControl::getTimer()
is called very frequently. During profiling, I noticed that during a call to getTimer()
, obc-j also calls objc_retain
and objc_release
(presumably on m_holder or m_holder.timer), which ends up sucking up a lot of time! Removing __unsafe_unretained
didn't make a difference.
By construction, I know that whenever ExternalControl::getTimer()
is called, m_holder and its timer will stay alive for the duration of the call, so I think the retains/releases are unnecessary.
Is there any way to prevent them from being called?
I'm using XCode 4.2 with iOS 5 SDK, with ARC enabled. Is ARC responsible and removing it would remove the retains/releases? (I didn't want to spend time re-creating a project without ARC just to test this, before checking with you my friends!)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我只能从非 ARC 的经验来谈,因为我还没有使用过它(并且不打算让它成为老派)。
但是,我有几个项目使用 C++ 库并在 obj-C 代码中保留对其的引用。
我知道除非明确请求,否则不会调用保留/释放。
顺便说一句,链接 C++ 库时我无法使用 Obj-C,而必须使用 Obj-C++,否则 C++ 构造函数/析构函数不会按预期调用。只需将 .m 文件重命名为 .mm
希望这会有所帮助。
I can only speak from a non-ARC experience as I haven't used it yet (and not planning it being old school).
However, I have several projects using a C++ library and keeping references to it in the obj-C code.
I know for a fact that retain/release isn't called unless explicitly requested.
BTW, I couldn't use Obj-C when linking the C++ library and instead had to use Obj-C++ otherwise the C++ constructor/destructors weren't called as expected. It was just a matter of renaming the .m file into .mm
Hope this help.
如果您想手动处理该类的保留/释放(禁用 ARC)。
在该源文件的构建阶段选项卡中设置“-fno-objc-arc”编译器标志。
If you want to manually handle retain/release for just that class (disable ARC).
set the "-fno-objc-arc" compiler flag in the build phases tab for that source file.
WWDC 2011 ARC 会议特别提到,在编译调试时,ARC 保留/释放并未优化。
如果还没有,请尝试在发布模式下运行代码并对其进行分析。您应该会看到显着差异。
但是,我知道 ARC 不会考虑您在说“通过构造”时所暗示的那种设计假设。但是,ARC 不应该触及您的“__unsafe_unretained”实例变量...您确定这些保留/释放调用正在传递指向那个的指针吗?
The WWDC 2011 sessions on ARC specifically mention that when compiled for debug, ARC retain/releases are not optimized.
If you haven't, try running your code in Release mode and profiling it. You should see a significant difference.
However, I know ARC doesn't take into account the kind of design assumptions you imply when you say "By construction". But, ARC shouldn't be touching your your "__unsafe_unretained" instance variable... are you sure those retain/release calls are being passed a pointer to that?