0

これを行う方法について何日も調査してきましたが、誰も答えがありません。

同じビューに 5 つのタイマーを持つアプリを作成しています。「15:00」(分と秒) からカウントダウンするタイマーと、「2:58」(分と秒) からカウントダウンする別のタイマーを作成する必要があります。15 分のタイマーは繰り返さないようにする必要がありますが、「00:00」に達したときに他のすべてのタイマーを停止する必要があります。「2:58」タイマーは、「15:00」または「ゲーム クロック」が 0 になるまで繰り返す必要があります。現在、ほとんどすべてのコードを廃棄し、「2:58」繰り返しタイマーに取り組んでいますまたは「ロケットタイマー」。

誰もこれを行う方法を知っていますか?

EDIT 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:たかどうかを確認するのを忘れていました...totalSeconds

2番目の問題

-(NSString *)timeFormatted:(int)newTotalSeconds期待どおりには機能しません。実際、Xcode が「'newTotalSeconds' のローカル宣言がインスタンス変数を隠しています」というコンパイラ警告を表示することは間違いありません。
試してみてください:で、行をStart行に置き換え、その後にブレークポイントを設定します。rocketCount.text = [self timeFormatted:newTotalSeconds];rocketCount.text = [self timeFormatted:42];

3 番目の問題 (実際には 1 つの場所にいくつかの問題があります)

あなたdeallocは明らかに間違っています:
何よりもまず、 の後に電話をかけるのは最善の考えではありません[super dealloc]。第二に、「あなたは間違っている」:あなたの方法を考えるとStart、あなたはタイマーを所有していないので、それをしてはいけません release。代わりに、タイマーがまだ有効である場合は、それが必要にinvalidateなります。しかし、スケジュールされている限り、viewController はed にならないため (他の場所でメモリ管理にエラーがない限り) 、これは問題にはなりません。以前の投稿で、この動作を説明するかなり完全な例を書きました。rocketTimerdealloc

それで、クラッシュの原因は何ですか?

正直なところ:
手がかりはありません!

正確に何が問題なのかを調べるために、ブレークポイントを に追加してみてください-[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初期化時に設定して組み込みの設定を使用することをお勧めします。

FirstViewController.h

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

FirstViewController.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 に答える