0

我一直在研究如何做到这一点,没有人有答案。

我正在同一视图上创建一个具有 5 个计时器的应用程序。我需要创建一个从“15:00”(分钟和秒)开始倒计时的计时器,以及另一个从“2:58”(分钟和秒)开始倒计时的计时器。15 分钟计时器不应重复,但应在达到“00:00”时停止所有其他计时器。“2:58”计时器应该重复,直到“15:00”或“游戏时钟”达到 0。现在,我已经废弃了几乎所有的代码,我正在研究“2:58”重复计时器,或“火箭计时器”。

有谁知道如何做到这一点?

编辑 2:我的模拟器甚至不会运行应用程序,所以我目前不知道计时器是否真的在工作,但从我之前的尝试来看,它没有工作。它没有以我想要的格式显示,并且按 2 倒计时(从它最后一次实际工作开始)。问题还在于,我对 Objective-C 并不流利。我可以像其他人一样整天编写伪代码,但我无法将我想要的东西放入代码中,因为我不完全理解 NSTimer。

编辑:

在我的输出中,我收到此错误“在抛出 'NSException' 的实例后调用终止”

这个错误?

我的错误

这是我的代码:

    #import <UIKit/UIKit.h>


@interface FirstViewController : UIViewController {



    //Rocket Timer
    int totalSeconds;
    bool timerActive;
    NSTimer *rocketTimer;
    IBOutlet UILabel *rocketCount;

    int newTotalSeconds;
    int totalRocketSeconds;
    int minutes;
    int seconds;

}

- (IBAction)Start;



@end

和我的.m

    #import "FirstViewController.h"

@implementation FirstViewController

- (NSString *)timeFormatted:(int)newTotalSeconds
{

    int seconds = totalSeconds % 60; 
    int minutes = (totalSeconds / 60) % 60; 


    return [NSString stringWithFormat:@"%i:%02d"], minutes, seconds; 
}


-(IBAction)Start {

    newTotalSeconds = 178; //for 2:58

    newTotalSeconds = newTotalSeconds-1;

    rocketCount.text = [self timeFormatted:newTotalSeconds];


    if(timerActive == NO){

        timerActive = YES;
        newTotalSeconds = 178;

      [rocketTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerLoop) userInfo:nil repeats:YES];
    }

    else{

        timerActive = NO;
        [rocketTimer invalidate];
        rocketTimer = nil;

    }

}



-(void)timerLoop:(id)sender {

    totalSeconds = totalSeconds-1;

    rocketCount.text = [self timeFormatted:totalSeconds];


}

- (void)dealloc
{
    [super dealloc];

    [rocketTimer release];


}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    timerActive = NO;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end
4

3 回答 3

3

你的代码有一些问题!
坏消息是,它们都与您所看到的崩溃无关。

第一个也是最明显的问题

实际上,您永远不会停止倒计时!

在您安排好计时器后Start,您的timerLoop:-method 将每秒被调用一次。但是你忘了检查是否totalSeconds已经变成负数了……

第二个问题

-(NSString *)timeFormatted:(int)newTotalSeconds不会像您期望的那样工作!实际上,我非常确定 Xcode 会给你一个编译器警告,指出“'newTotalSeconds' 的本地声明隐藏实例变量”
试一试:在Start中,用该行替换该行rocketCount.text = [self timeFormatted:newTotalSeconds];rocketCount.text = [self timeFormatted:42];在其后设置一个断点。

第三个问题(实际上是一个地方的几个问题)

dealloc是完全错误
的:首先,在[super dealloc]. 其次,“你做错了”:考虑到你的Start方法,你不拥有计时器,所以你不能 release这样做。相反,如果计时器仍然有效,您就需要invalidate它。但这甚至不会成为问题,因为只要rocketTimer安排好,您的 viewController 就不会被dealloc编辑(除非您在其他地方的内存管理中有错误)。我在之前的文章中写了一个相当完整的示例来解释这种行为。

那么,是什么原因导致了坠机呢?

老实说:
不知道!

为了找出究竟出了什么问题,请尝试将断点添加到-[NSException raise]. 或者,您可以将main函数修改main.m为以下内容:

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int response;
    @try {
        response = UIApplicationMain(argc, argv, nil, nil);
    } @catch (NSException *e) {
        NSLog(@"%@: %@\nCall-stack:\n%@", [e name], [e reason], [e callStackSymbols]);
        response = 1;
    }
    return response;
}

这将告诉您程序实际崩溃的方法。

于 2011-03-20T21:30:49.703 回答
1

在哪里rocketTimer实例化?你似乎遗漏了那个非常重要的细节。我的猜测是rocketTimer您的代码没有正确保留它,这会导致您在释放该对象后尝试访问该对象时崩溃。

self.rocketTimer我建议综合您的属性,然后在初始化时通过设置使用内置设置。

第一视图控制器.h

@interface FirstViewController : UIViewController {
    NSTimer *rocketTimer;
}
@property (nonatomic, retain) NSTimer *rocketTimer;
- (IBAction)Start;
@end

第一视图控制器.m

@implementation FirstViewController
@synthesize rocketTimer;
// test of implementation
// ...
于 2011-03-20T02:39:00.870 回答
0

如果问题是它没有重复,我会让 timerLoop 方法在减法之前检查 totalSeconds 的值。如果它是 0,让它再次设置为 178。

如果问题出在其他地方,请告诉我们在哪里,并提供更多信息,说明问题出在哪里以及您下次已经尝试过什么。

于 2011-03-19T15:57:19.480 回答