【问题标题】:Cocos2d-x, Create_func and init method, immediately call destructorCocos2d-x,Create_func和init方法,立即调用析构函数
【发布时间】:2013-11-29 15:55:03
【问题描述】:

我习惯于使用 Objective-C 和 Cocos2d,所以这让我感到困惑。

我确实想将一些自定义对象保存到二维数组中,所以我正在这样做,在我想要数组的类的标题中:

public:

SomeClass *matrix[6][6];

在我做的 init 方法中的 .cpp 中:

this->matrix[0][0] = SomeClass::create();

如果我这样做,构造函数、init 和析构函数将按此顺序调用......显然,让我感到困惑的是析构函数调用。

如果我这样做:

this->matrix[0][0] = new SomeClass;

SomeClass 是 CCNode 的子类。

构造函数被调用,这很好......但是由于我确实想将init方法与create一起使用,我应该怎么做?我不知道为什么创建方法会在方法返回时立即调用析构函数。

我真的不明白 init 方法和 Create_func 到底发生了什么,因为我是 Cocos2d-x 的新手,所以我想更好地理解这一点。

这是我正在使用的创建函数:

#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
    __TYPE__ *pRet = new __TYPE__(); \
    if (pRet && pRet->init()) \
    { \
       pRet->autorelease(); \
       return pRet; \
     } \
     else \
     { \
        delete pRet; \
        pRet = NULL; \
        return NULL; \
      } \
}

【问题讨论】:

  • 请显示SomeClass::create()函数。
  • 我正在使用在基本 Cocos2d-x 项目中找到的已定义 CREATE_FUNC() 宏,它在 CCPlatformMacros.h 中,我在问题中添加了 func
  • SomeClass::init() 返回什么?
  • 这可能是因为 cocos2d-x 模拟了 objc 的保留/释放/自动释放行为。您必须“保留”创建的对象。
  • cocos2d-x中init方法返回一个bool,cocos2d中返回一个id。顺便说一句,我的 init 是“空的”。但是,您能给我一些关于如何“保留”创建的对象的建议吗?我相信你是对的,因为实际上使用 new Object 它可以工作,所以它被保留了,但是如果我使用 create_func 我以后如何手动保留该对象?

标签: c++ cocos2d-x destructor init


【解决方案1】:

所以首先,让我解释一下 cocos2d-x 内存管理是如何工作的。

由于 cocos2d-x 与 cocos2d 相关,cocos2d-x 团队愿意在 object-c 中使用保留/释放的东西。

很明显,一个CCObject只有当他的retain值大于0时才会被保存在内存中。

一旦调用函数release();,这个对象的retain值会减1,如果达到0,就会调用析构函数。

最后是 autorelase() 函数。是什么,对于cocos2d-x,核心线程在CCPoolManager::sharedPoolManager()中持有一个CCArray。在每一帧中,这个数组中的所有对象都会调用一次release(),如果retain value == 0,就会被移除。

那么让我们来看看这个案例吧。

我相信 autorelease() 是让你感到困惑的原因。 当一个对象被 new ClassName() 创建时,retain == 1; 但是如果调用autorelease(),它仍然是1,但是下一帧会是0。

这就是为什么当你使用 this->matrix[0][0] = SomeClass::create();构造函数、init 和析构函数将被一一调用,但请记住,析构函数是在下一帧中调用的,而不是在 init() 之后立即调用。

那么如何使这些正确,有很多方法可以做到这一点。 最简单的方法是: this->matrix[0][0] = SomeClass::create(); this->matrix[0][0]->retain();

除此之外,我强烈建议使用 CC_SYNTHESIZE_RETAIN(varType, varName, funName) 在头文件中定义一个值,而不是 ClassName* valueName。

并使用 set##funName(varType var) 来设置它,而不是使用 valueName = ClassName::create()。

有关更多信息,您可以阅读 CC_SYNTHESIZE_RETAIN marco。

【讨论】:

    【解决方案2】:

    只需使用retain()..

    SomeClass *newObject=SomeClass::create();
    newObject->retain();
    this->matrix[0][0] = newObject;
    

    然后您需要稍后在删除此数组之前手动释放对象,否则可能会发生内存泄漏。

    【讨论】:

      猜你喜欢
      • 2014-09-18
      • 1970-01-01
      • 2019-04-08
      • 2012-03-31
      • 2010-09-13
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多