1

newsTimer fires every 35 seconds, but it runs runNews 2 times. I get the NSLog that I setup in runNews 2 times every time it fires.

   -(id)init
{
    if ([super init]) {
        [self loadDefaults];
        NSTimer *newsTimer = [NSTimer scheduledTimerWithTimeInterval:35.0 target:self selector:@selector(runNews) userInfo:nil repeats:YES];

    }
    return self;
}



    -(void)runNews
{
    NSMutableArray *headingArray;
    if (_currentTips < 20) {
        headingArray = [NSMutableArray arrayWithObjects:@"Text 1", @"Text 2",
    }

    int randomGen = arc4random_uniform(headingArray.count - 1.0);
    NSString *headingString = [NSString stringWithString:headingArray[randomGen]];
    headingLabel = [[CCLabelTTF alloc] initWithString:headingString fontName:@"Minecraftia-Regular.ttf" fontSize:12.0];
    [headingLabel setPositionType:CCPositionTypeMake(CCPositionUnitPoints, CCPositionUnitPoints, CCPositionReferenceCornerTopRight)];
    [headingLabel setPosition:ccp(-200, 38)];
    [headingLabel setFontColor:([CCColor greenColor])];
    [self addChild:headingLabel];
    [headingLabel runAction:([CCActionMoveTo actionWithDuration:20.0 position:ccp(500, 38)])];
    NSLog(@"Running news");
    [headingLabel performSelector:@selector(removeFromParent) withObject:nil afterDelay:20.0];
}

I can't see any reason why this would run twice... Any ideas?

SaleenS7
  • 402
  • 4
  • 15
  • 1
    I can think of two immediate possibilities. You might have another timer somewhere (not shown). Or, you might have two instances of this class, each with its own timer, each with its own `runNews`. Try logging `self` when you log `runNews` and see if the two `self` instances have the same address. – matt Dec 24 '14 at 02:46
  • 2
    I'm guessing you somehow have two timers. Change your runNews method to accept the `NSTimer*` parm and then NSLog the timer address when it's called. Likely you will see two separate addresses. And also log the `self` address, to see if you have two separate instances of your class. – Hot Licks Dec 24 '14 at 03:11
  • try something like this: @implementation YourClass {NSTimer* _newsTimer;} ... _newsTimer = ... instead of NSTimer* newsTimer = ... – stosha Dec 24 '14 at 03:12
  • or add NSLog in dealloc: - (void) dealloc{NSLog(@"%d", _currentTips);}; – stosha Dec 24 '14 at 03:17
  • 1
    avoid use of NSTimer with cocos2d : see http://stackoverflow.com/questions/5225227/nstimer-in-cocos2d-application – YvesLeBorg Dec 24 '14 at 03:48
  • Do not overload init and it will work just fine. – MoDJ Dec 24 '14 at 04:26
  • 1
    more details about why not to use nstimer here: http://stackoverflow.com/a/23978854/201863 – CodeSmile Dec 24 '14 at 17:38
  • Thanks guys, I solved this with YvesLeBorg's answer. I'm curious though, as to why having two timers would cause this to happen if the selectors are different. Is it not possible to have two timers at one time? – SaleenS7 Dec 24 '14 at 21:28

1 Answers1

1

Not certain about why this method runs twice (possibly 2 instances as Hot Licks suggested). Here is how i would structure this, in order to play nicely with cocos2d's scheduling and "single threaded'ness"

aka , avoid NSTimer and performSelector.

You need to execute display defining bits of code like entirely within cocos2d's run loop, update cycle, etc, and avoid tinkering with the main thread, in order to promote smooth rendering and avoid jitter :

-(id)init
{
    if (self = ([super init]) {  // <=== did you forget to set self ?
        [self loadDefaults];
    }
    return self;
}

-(void) onEnter {
    [super onEnter];    // now this CCNode will be scheduled etc ...
    [self schedule:@selector(runNews) interval:35.0f]; // cocos will schedule this properly
}

-(void)runNews
{
    NSMutableArray *headingArray;
    if (_currentTips < 20) {
        headingArray = [NSMutableArray arrayWithObjects:@"Text 1", @"Text 2",
    }
    int randomGen = arc4random_uniform(headingArray.count - 1.0);
    NSString *headingString = [NSString stringWithString:headingArray[randomGen]];
    headingLabel = [[CCLabelTTF alloc] initWithString:headingString fontName:@"Minecraftia-Regular.ttf" fontSize:12.0];
    [headingLabel setPositionType:CCPositionTypeMake(CCPositionUnitPoints, CCPositionUnitPoints, CCPositionReferenceCornerTopRight)];
    [headingLabel setPosition:ccp(-200, 38)];
    [headingLabel setFontColor:([CCColor greenColor])];
    id move = [CCActionMoveTo actionWithDuration:20.0 position:ccp(500, 38)];
    id clean = [CCCallBlock actionWithBlock:^{
        NSLog(@"label %08X [%@] ends move.",(int) headingLabel,headingLabel.string);
        [headingLabel removeFromParentAndCleanup:YES];
    }];
    id seq = [CCActionSequence actions:move,clean,nil];
    [self addChild:headingLabel];
    NSLog(@"label %08X [%@] starts move.",(int) headingLabel,headingLabel.string);
    [headingLabel runAction:seq];
}
YvesLeBorg
  • 9,070
  • 8
  • 35
  • 48