Problems with createWithSpriteFrame

Greetings!
I have a problem with createWithSpriteFrame function. Some ASSERT is appearing during the call. Here is the code:

   std::vector animParams;
    if (LoadAnimParamsFromFile("anims.xml", animParams))
    {
        CCAnimate* pAnimation = LoadAnimByParams("skull_anim.png", animParams, 0.5f, false);
        if (!pAnimation)
            return false;

        CCSpriteFrame* pSprFrame = (CCSpriteFrame*) pAnimation->getAnimation()->getFrames()->objectAtIndex(0);
        m_pSkull = CCSprite::createWithSpriteFrame(pSprFrame ); // <---Problem is here!
        m_pSkull->setPosition(ccp(300, 300));
        this->addChild(m_pSkull, 2);

        CCFiniteTimeAction* pAnimReverse = pAnimation->reverse();
        CCSequence* pSeq = CCSequence::createWithTwoActions(pAnimation, pAnimReverse);
        CCRepeatForever* pAlways = CCRepeatForever::create(pSeq);

        m_pSkull->runAction(pAlways);
    }

I tried to check all things to be correct(pointers to objects, textures) but found nothing ecxept on thing: when I was tracing the problem function(e.g. createWithSpriteFrame) I found that some pointer to texture had a strange value. Here some parts of code where I had found some mysteries:

  1. m_pobTexture = 0x00000778. I think this is strange value.

    CCTexture2D* CCSpriteFrame::getTexture(void)
    {
    if( m_pobTexture ) {
    return m_pobTexture;
    }

     if( m_strTextureFilename.length() > 0 ) {
         return CCTextureCache::sharedTextureCache()->addImage(m_strTextureFilename.c_str());
     }
     // no texture or texture filename
     return NULL;
    

    }

  2. The assertion happens here:

    void CCSprite::setTexture(CCTexture2D *texture)
    {
    // If batchnode, then texture id should be the same
    CCAssert(! m_pobBatchNode || texture->getName() == m_pobBatchNode->getTexture()->getName(), “CCSprite: Batched sprites should use the same texture as the batchnode”);
    // accept texture==nil as argument
    CCAssert( !texture || dynamic_cast(texture), “setTexture expects a CCTexture2D. Invalid argument”);

     if (!m_pobBatchNode && m_pobTexture != texture)
     {
         CC_SAFE_RETAIN(texture);   // < --------- Assertion here 
         CC_SAFE_RELEASE(m_pobTexture);
         m_pobTexture = texture;
         updateBlendFunc();
     }
    

    }

In conclusion the part of code of LoadAnimByParams function, but I’m not sure if it is really needed:

CCAnimate* HelloWorld::LoadAnimByParams(const std::string& imgName, const std::vector& params, float delay, bool bUsePivotParams/* = false*/)
{
    //_LOG("LoadAnimByParams");
    CCTexture2D* pTexture = CCTextureCache::sharedTextureCache()->textureForKey(imgName.c_str());
    if (!pTexture)
    {
        return NULL;
    }

    // Читаем параметры анимации
    unsigned int params_count = params.size();
    CCSpriteFrame** pSpriteFrames = new CCSpriteFrame*[params_count];
    for (unsigned int i = 0; iaddObject(pSpriteFrames[i]);
    }

    delete []pSpriteFrames;

    CCAnimation* pLocalAnimation = CCAnimation::createWithSpriteFrames(pAnimFrames, delay);
    if (!pLocalAnimation)
    {
        pAnimFrames->release();
        return NULL;
    }

    CCAnimate* pAnimate = CCAnimate::create(pLocalAnimation);
    if (!pAnimate)
    {
        pAnimFrames->release();
        return NULL;
    }

    pAnimFrames->release();

    //_LOG("LoadAnimByParams - end");

    return pAnimate;
}

Thanks in advance.

What did the assertion say?

Nite Luo wrote:

What did the assertion say?

hm… now I think that this is not an assertion. This is just a bad pointer object. The message is: “Unhandled exception at 0x1001b92b (libcocos2d.dll) in Wizards.win32.exe: 0xC0000005: Access violation reading location 0x00000784.” in this part of code:

void CCObject::retain(void)
{
    CCAssert(m_uReference > 0, "reference count should greater than 0");

    ++m_uReference;
}

with this = 0x00000778

At last, I’ve found the problem, but still little confused about it… The problem was in this part of code:

CCSpriteFrame* pSprFrame = (CCSpriteFrame*) pAnimation->getAnimation()->getFrames()->objectAtIndex(0);
        m_pSkull = CCSprite::createWithSpriteFrame(pSprFrame ); // <---Problem is here!

should be…

        CCAnimationFrame* pSprFrame = (CCAnimationFrame*) pAnimation->getAnimation()->getFrames()->objectAtIndex(0);
        m_pSkull = CCSprite::createWithSpriteFrame(pSprFrame->getSpriteFrame());

I think this is a mistake of designing. You push some sprite frames into an object and when you want it back you get another type of object… In my case spriteFrame changes into animationFrames. This hidden transformation shouldn’t have place I think.