【已解决】关于autorelease自动内存管理问题,为什么会出现问题?

写了如下一段代码,输出VOCellNode的引用计数和一个字符串内容,然后加入了一个计划任务每次都输出引用计数和字符串,结果发现第三次之后VOCellNode的引用计数不对了,字符串内容也不对了,而且 析构函数也会被调用,然后输出析构函数的内容,是不是出现了野指针?

#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"


#include "MapEnum.h"

USING_NS_CC;

using namespace cocostudio::timeline;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

void HelloWorld::test(float t)
{
    
    CCLOG("references:%u  %s", vo->getReferenceCount(), vo->str.c_str());
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    vo = VOCellNode::create();
    vo->str = "VOCellNode";
    
    CCLOG("references:%u  %s", vo->getReferenceCount(), vo->str.c_str());
    
    this->schedule(schedule_selector(HelloWorld::test));
    return true;
}


```


//
//  VOCellNode.cpp
//  TurnTableRPG
//
//  Created by hanxianming on 15/4/7.
//
//

#include "VOCellNode.h"

bool VOCellNode::init()
{
    return true;
}

VOCellNode::~VOCellNode()
{
    CCLOG("~VOCellNode");
}


```



//
//  VOCellNode.h
//  TurnTableRPG
//
//  Created by hanxianming on 15/4/7.
//
//

#ifndef __TurnTableRPG__VOCellNode__
#define __TurnTableRPG__VOCellNode__

class VOCellNode : public cocos2d::Ref
{
public:
    cocos2d::Color3B color;
    std::string str;
    
    ~VOCellNode();
    
    virtual bool init();
    
    CREATE_FUNC(VOCellNode);
    
private:
    
};


#endif /* defined(__TurnTableRPG__VOCellNode__) */



```

求助高手,解答疑问!

由于你的VOCellNode::create设置了autorelease,所以第三次输出的时候vo已经被析构了

那意思就是可以说 类的成员变量(类型是Ref的子类,比如说自定义的或者Node这种),就不可以使用autorelease?
或者说在使用成员变量的时候需要手动显示的调用一下retain,

按照你前面的示例程序来看,是必须要retain一下的
一般情况下,由于node都会被addchild到另外一个node上,addchild的时候会自动做retain,所以只要add过了就不必担心了,直到被remove的时候或者父node销毁的时候才会被销毁

非常感谢,已经查看相关的帖子,已经解决疑惑和问题。

如下贴出答案和帖子链接分享给大家:

[retain release autorelease怎么用?

获得对象后用retain,释放对象用release或者autorelease,就这么简单。

重复下原因:retain计数器加一; release计数器减一;autorelease将对象加入autoreleasepool,在mainLoop下次会调用autoreleasepool的clear导致对象的release被调用(autorelease相当于间接调用release) 。

提一提create函数,cocos的2段构造实现,它作的工作:new一个对象,计数器默认为1;将对象放入了autoreleasepool。 故mainLoop下次循环就会被释放。 要想持有,那就create之后调用retain,并在owner的适当地方如析构函数调用release或autorelease即可。

提一提addChild函数,最终调用到Node::insertChild,并最终调用到Vector::pushBack,导致child的retain被调用一次。故常见情况是通过create函数创建obj(引用计数=1),通过addChild来加到相关父容器(引用计数=2)。 (下一次mainLoop,autoreleasepool clean,引用计数变1,对象被父容器拥有) 这一create 一addChild最终导致父容器来拥有obj。

理解了这些之后, 实际用起来应该不乱了。


```


链接地址:http://cn.cocos2d-x.org/tutorial/show?id=2300