scheduledTimerWithTimeInterval仅在Repeats设置为YES时触发一次

时间:2011-06-20 05:39:18

标签: objective-c ios cocoa-touch nstimer

我正在参加其中一本Apress书籍的练习。在这段代码中,创建了一个NSTimer对象,该对象应该重复触发并调用gameloop函数。我在gameloop中设置了断点,它只触发一次。我想知道为什么。就应该做的事而言,这似乎相当简单。有没有人有关于这里可能发生的事情的指导?

#define RANDOM_SEED() srandom(time(NULL))
#define RANDOM_INT(__MIN__, __MAX__) ((__MIN__) + random() % ((__MAX__+1) - (__MIN__)))
#define kSteps 8
#define kSpeed 200
#define kFPS 20.0
#define kBounce 30
#define kDirForward 0
#define kDirBackward 1
#define kDirUp 2
#define kDirDown 3
static int kForward[] =  {0,1,2,3,4,5,6,7};
static int kUpward[] =   {8,9,10,11,12,13,14,15};
static int kDownward[] = {16,17,18,19,20,21,22,23};
static int kBackward[] = {24,24,25,26,27,28,29,30};


/** for mario.png
#define kSteps 6
static int kForward[] = {10,11,11,10,9,9};
static int kBackward[] = {22,23,23,22,21,21};
static int kUpward[] = {4,5,5,4,3,3};
static int kDownward[] = {16,17,17,16,15,15};
**/

- (id) initWithCoder: (NSCoder *) coder {
    if (self = [super initWithCoder: coder]) {
        test = [AtlasSprite fromFile: @"walk.png" withRows: 4 withColumns: 8];
        test.angle = 0;
        test.speed = kSpeed;
        direction = kDirForward;
        timer = [NSTimer scheduledTimerWithTimeInterval: 1.0/kFPS
                                                     target:self 
                                               selector:@selector(gameLoop) 
                                               userInfo:nil 
                                                repeats:YES];
        self.backgroundColor = [UIColor whiteColor];
    }
    return self;
}

- (void) gameLoop
{
    frame = (frame+1)%kSteps;
    [test tic: 1.0/kFPS];
    if (test.offScreen) {
        RANDOM_SEED();
        int toCenter = round(atan2(-test.y,-test.x)*180.0/3.141592);
        if (toCenter < 0) toCenter += 360;
        int bounce = (toCenter+RANDOM_INT(-kBounce,kBounce))%360;
        if (bounce <= 60 || bounce >= 300) direction = kDirForward;
        else if (bounce > 60 && bounce < 120) direction = kDirUp;
        else if (bounce >= 120 && bounce <= 240) direction = kDirBackward;
        else direction = kDirDown;
        test.angle = bounce;
        test.scale = 0.4+1.6*RANDOM_INT(0,10)/10.0;
        while (test.offScreen) [test tic: 1.0/kFPS];
    }
    switch (direction) {
        case kDirForward:       test.frame = kForward[frame]; break;
        case kDirBackward:      test.frame = kBackward[frame]; break;
        case kDirUp:            test.frame = kUpward[frame]; break;
        case kDirDown:          test.frame = kDownward[frame]; break;
    }
    [self setNeedsDisplay];
}

1 个答案:

答案 0 :(得分:0)

富:

NSTimer是一个自动释放的对象。因为您希望重复它,所以您需要保留该对象。试试这个:

timer = [[NSTimer scheduledTimerWithTimeInterval: 1.0/kFPS
                                                 target:self 
                                           selector:@selector(gameLoop) 
                                           userInfo:nil 
                                            repeats:YES] retain];

通过保留计时器,您需要确保在不再需要时将其释放。确保在完成计时器后使计时器失效。

我希望这可以解决您的问题。