【发布时间】:2015-11-05 12:19:20
【问题描述】:
我正在开发 cocos2dx v3.3。每当使用 Release 或 autorelease 发布图像时,Android 中就会发生随机崩溃,但它在 iOS 中运行良好。
谁能帮助或指导我如何处理这些崩溃?
【问题讨论】:
我正在开发 cocos2dx v3.3。每当使用 Release 或 autorelease 发布图像时,Android 中就会发生随机崩溃,但它在 iOS 中运行良好。
谁能帮助或指导我如何处理这些崩溃?
【问题讨论】:
cocos2d-x 为内存管理实现了一个类似 OC 的引用计数方案。
这种崩溃通常是由错误的引用计数引起的。当你release 或autorelease 一个Ref 时,你应该确保它之前已经retained,这样它的引用计数不为零。
更多细节可以参考CCRef.cpp下面的代码sn-p(注意:cmets更重要):
void Ref::release()
{
CCASSERT(_referenceCount > 0, "reference count should be greater than 0");
--_referenceCount;
if (_referenceCount == 0)
{
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
auto poolManager = PoolManager::getInstance();
if (!poolManager->getCurrentPool()->isClearing() && poolManager->isObjectInPools(this))
{
// Trigger an assert if the reference count is 0 but the Ref is still in autorelease pool.
// This happens when 'autorelease/release' were not used in pairs with 'new/retain'.
//
// Wrong usage (1):
//
// auto obj = Node::create(); // Ref = 1, but it's an autorelease Ref which means it was in the autorelease pool.
// obj->autorelease(); // Wrong: If you wish to invoke autorelease several times, you should retain `obj` first.
//
// Wrong usage (2):
//
// auto obj = Node::create();
// obj->release(); // Wrong: obj is an autorelease Ref, it will be released when clearing current pool.
//
// Correct usage (1):
//
// auto obj = Node::create();
// |- new Node(); // `new` is the pair of the `autorelease` of next line
// |- autorelease(); // The pair of `new Node`.
//
// obj->retain();
// obj->autorelease(); // This `autorelease` is the pair of `retain` of previous line.
//
// Correct usage (2):
//
// auto obj = Node::create();
// obj->retain();
// obj->release(); // This `release` is the pair of `retain` of previous line.
CCASSERT(false, "The reference shouldn't be 0 because it is still in autorelease pool.");
}
#endif
#if CC_REF_LEAK_DETECTION
untrackRef(this);
#endif
delete this;
}
}
【讨论】: