从 C++ 调用 Obj-C 消息时如何防止自动保留/释放?

发布于 2024-12-10 19:30:29 字数 919 浏览 0 评论 0原文

我有一些这样的代码:

@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_retainobjc_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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小情绪 2024-12-17 19:30:29

我只能从非 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.

洛阳烟雨空心柳 2024-12-17 19:30:29

如果您想手动处理该类的保留/释放(禁用 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.

夜访吸血鬼 2024-12-17 19:30:29

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文