title: Cocos2D -[CCSpriteFrame delayUnits]: unrecognized selector sent to instance
body: <p>I followed an on-line guide (<a href="http://www.raywenderlich.com/2593/how-to-create-a-mole-whacking-game-with-cocos2d-part-2" rel="nofollow">How To Create A Mole Whacking Game with Cocos2D</a>), but my application crash run-time with this error:</p>
  
  <pre><code>2013-02-19 16:03:23.028 WhackAMole[3616:907] -[CCSpriteFrame
  delayUnits]: unrecognized selector sent to instance 0x1f548ce0
  </code></pre>
  
  <p>If I add an Exception Breakpoint Xcode will pause the code execution in this function (Cocos2D):</p>
  
  <pre><code>-(id) initWithAnimationFrames:(NSArray*)arrayOfAnimationFrames delayPerUnit:(float)delayPerUnit loops:(NSUInteger)loops
  {
      if( ( self=[super init]) )
      {
          delayPerUnit_ = delayPerUnit;
          loops_ = loops;
  
          self.frames = [NSMutableArray arrayWithArray:arrayOfAnimationFrames];
  
          for( CCAnimationFrame *animFrame in frames_ )
              totalDelayUnits_ += animFrame.delayUnits;  //Crash here
      }
      return self;
  }
  </code></pre>
  
  <p>By the way this is the code:</p>
  
  <pre><code>#import "GameScene.h"
  
  @implementation GameScene
  
  + (id)scene
  {
      // the usual ... create the scene and add our layer straight to it
      CCScene *scene = [CCScene node];
      CCLayer* layer = [GameScene node];
      [scene addChild:layer];
      return scene;
  }
  
  #pragma mark - Life Cycle
  
  - (id)init
  {
      // Determine names of sprite sheets and plists to load
      NSString *bgSheet = @"background.pvr.ccz";
      NSString *bgPlist = @"background.plist";
      NSString *fgSheet = @"foreground.pvr.ccz";
      NSString *fgPlist = @"foreground.plist";
      NSString *sSheet = @"sprites.pvr.ccz";
      NSString *sPlist = @"sprites.plist";
      if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
          bgSheet = @"background-hd.pvr.ccz";
          bgPlist = @"background-hd.plist";
          fgSheet = @"foreground-hd.pvr.ccz";
          fgPlist = @"foreground-hd.plist";
          sSheet = @"sprites-hd.pvr.ccz";
          sPlist = @"sprites-hd.plist";
      }
  
      if ((self = [super init]))
      {
          [self setScreenSaverEnabled:NO];     
  
          // Load background and foreground
          [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:bgPlist];
          [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:fgPlist];
  
          // Add background
          CGSize winSize = [CCDirector sharedDirector].winSize;
          CCSprite *dirt = [CCSprite spriteWithSpriteFrameName:@"bg_dirt.png"];
          dirt.scale = 2.0;
          dirt.position = ccp(winSize.width/2, winSize.height/2);
          [self addChild:dirt z:-2];
  
          // Add foreground
          CCSprite *lower = [CCSprite spriteWithSpriteFrameName:@"grass_lower.png"];
          lower.anchorPoint = ccp(0.5, 1);
          lower.position = ccp(winSize.width/2, winSize.height/2);
          [self addChild:lower z:1];
  
          CCSprite *upper = [CCSprite spriteWithSpriteFrameName:@"grass_upper.png"];
          upper.anchorPoint = ccp(0.5, 0);
          upper.position = ccp(winSize.width/2, winSize.height/2);
          [self addChild:upper z:-1];
  
          CCSpriteBatchNode *spriteNode = [CCSpriteBatchNode batchNodeWithFile:sSheet];
          [self addChild:spriteNode z:0];
          [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:sPlist];
  
          moles = [[NSMutableArray alloc] init];
  
          CCSprite *mole1 = [CCSprite spriteWithSpriteFrameName:@"mole_1.png"];
          mole1.position = CGPointMake(85, 85);
          [spriteNode addChild:mole1];
          [moles addObject:mole1];
  
          CCSprite *mole2 = [CCSprite spriteWithSpriteFrameName:@"mole_1.png"];
          mole2.position = CGPointMake(240, 85);
          [spriteNode addChild:mole2];
          [moles addObject:mole2];
  
          CCSprite *mole3 = [CCSprite spriteWithSpriteFrameName:@"mole_1.png"];
          mole3.position = CGPointMake(395, 85);
          [spriteNode addChild:mole3];
          [moles addObject:mole3];
  
          [self schedule:@selector(tryPopMoles:) interval:0.5];
  
          laughAnim = [self animationFromPlist:@"laughAnim" delay:0.1];
          hitAnim = [self animationFromPlist:@"hitAnim" delay:0.02];
          [[CCAnimationCache sharedAnimationCache] addAnimation:laughAnim name:@"laughAnim"];
          [[CCAnimationCache sharedAnimationCache] addAnimation:hitAnim name:@"hitAnim"];
      }
  
      return self;
  }
  
  -(void) dealloc
  {
      [moles release];
      moles = nil;
  
      [super dealloc];
  }
  
  #pragma mark - Mole Managment
  
  - (void)tryPopMoles:(ccTime)dt
  {
      for (CCSprite *mole in moles)
      {
          if (arc4random() % 3 == 0)
          {
              if (mole.numberOfRunningActions == 0)
              {
                  [self popMole:mole];
              }
          }
      }
  }
  
  - (void) popMole:(CCSprite *)mole
  {
      CCMoveBy *moveUp = [CCMoveBy actionWithDuration:0.2 position:CGPointMake(0, mole.contentSize.height)];
      CCEaseInOut *easeMoveUp = [CCEaseInOut actionWithAction:moveUp rate:3.0];
      CCAction *easeMoveDown = [easeMoveUp reverse];
      CCAnimate *laugh = [CCAnimate actionWithAnimation:laughAnim];
      laughAnim.restoreOriginalFrame = YES;
  
      [mole runAction:[CCSequence actions:easeMoveUp, laugh, easeMoveDown, nil]];
  }
  
  - (CCAnimation *)animationFromPlist:(NSString *)animPlist delay:(float)delay
  {
  
      //NSString *plistPath = [[NSBundle mainBundle] pathForResource:animPlist ofType:@"plist"];
      //NSArray *animImages = [NSArray arrayWithContentsOfFile:plistPath];
      NSMutableArray *animFrames = [NSMutableArray array];
      /*
      for(NSString *animImage in animImages)
      {        
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:animImage]];
      }
      */
  
      if ([animPlist isEqual: @"hitAnim"])
      {
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump1.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump2.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump3.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump4.png"]];
  
          return [CCAnimation animationWithAnimationFrames:animFrames delayPerUnit:delay loops:6];
      }
  
      else
      {
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh1.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh2.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh3.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh2.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh3.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh1.png"]];
  
          return [CCAnimation animationWithAnimationFrames:animFrames delayPerUnit:delay loops:6];
      }
  }
  
  #pragma mark - Misc
  
  -(void) setScreenSaverEnabled:(bool)enabled
  {
      UIApplication *thisApp = [UIApplication sharedApplication];
      thisApp.idleTimerDisabled = !enabled;
  }
  
  @end
  </code></pre>
  
  <p>Can someone help me?</p>
  
  <p>Thanks in advance...</p>
  
  <p><strong>SOLVED</strong></p>
  
  <p>Instead of using: <code>return [CCAnimation animationWithAnimationFrames:animFrames delayPerUnit:delay loops:6];</code></p>
  
  <pre><code>    NSMutableArray *animFrames = [NSMutableArray array];
  
      if ([animPlist isEqual: @"hitAnim"])
      {
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump1.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump2.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump3.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_thump4.png"]];
  
          return [CCAnimation animationWithAnimationFrames:animFrames delayPerUnit:delay loops:6];
      }
  
      else
      {
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh1.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh2.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh3.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh2.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh3.png"]];
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mole_laugh1.png"]];
  
          return [CCAnimation animationWithAnimationFrames:animFrames delayPerUnit:delay loops:6];
      }
  </code></pre>
  
  <p>I decided to use: <code>[CCAnimation animationWithSpriteFrames:animFrames delay:delay]</code></p>
  
  <pre><code>NSString *plistPath = [[NSBundle mainBundle] pathForResource:animPlist ofType:@"plist"];
      NSArray *animImages = [NSArray arrayWithContentsOfFile:plistPath];
      NSMutableArray *animFrames = [NSMutableArray array];
  
      for(NSString *animImage in animImages)
      {        
          [animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:animImage]];
      }
  
      return [CCAnimation animationWithSpriteFrames:animFrames delay:delay]; //Here's the
                                                                             //main
                                                                             //difference
  </code></pre>