-1

関数がループをループするたびに遅延を実行できるようにしたい。以下に示すように、すでにループ設定があります。

for (float batteryPercentage = 1; batteryPercentage <= 0; batteryPercentage -= 0.01)
    {
        double timeUntilNextDegreeDrop = 9.0;
        dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeUntilNextDegreeDrop * NSEC_PER_SEC));
        dispatch_after (time, dispatch_get_main_queue(), ^(void)
        {
            [batteryLevel setProgress:batteryPercentage animated:YES];

            float batteryLevelPercentage = batteryPercentage * 100;
            batteryLevelLabel.text = [NSString stringWithFormat:@"Battery Level: %f%%", batteryLevelPercentage];
        });
    }

batteryPercentageは、値が 0 になるまで 9 秒ごとに 0.01 ずつ 1 から 0 にデクリメントしようとしている変数です。プログラムの合計の長さは 900 秒 (15 分) である必要があります。9 秒ごとに、このコードを 9 秒ごとに実行して、UIProgressView呼び出された の値を変更する必要がありますbatteryLevel。次に、batteryPercentage0.67 を掛けて 67 を取得するなど、100 を掛けてパーセンテージ全体を取得し、batteryLevelLabelテキストを新しい値に置き換えます。これを実行しようとすると、batteryLevel進行状況ビューがいっぱいにならず、テキストが変化しません。タイマーに問題があると思いますが、9 秒の遅延を入力するより効果的な方法は何でしょうか?

4

3 に答える 3

0

NSThread を使用して既存の構造に近づける方法を次に示します。

@interface MyThread : NSThread
@end

@implementation MyThread

-(void)main
{
    NSDate * when = [ NSDate date ] ;

    for ( int battery = 1000; battery >= 0; battery -= 1 )
    {
        when = [ NSDate dateWithTimeInterval:1.0 sinceDate:when ] ;
        [ NSThread sleepUntilDate:when ] ;

        [ [ NSThread mainThread ] perform:^{
            [batteryLevel setProgress:(CGFloat)battery / 10.0 animated:YES];
            batteryLevelLabel.text = [NSString stringWithFormat:@"Battery Level: %f%%", (CGFloat)battery / 10.0 ];
        }];
    }
}

@end

ヘルパー カテゴリ:

@implementation NSThread (Perform)

-(void)_perform:(void(^)())block
{
    block() ;
}

-(void)perform:(void(^)())block
{
    BOOL wait = [ NSThread currentThread ] == self ;
    [ self performSelector:@selector( _perform: ) onThread:self withObject:[ block copy ] waitUntilDone:wait ] ;
}

@end

次に、タイマーを開始しますNSThread * thread = [ [ MyThread alloc ] init ] ; [ thread start ] ;

おそらく、標準の NSTimer + コールバック構造を使用するようにアプリを作り直す方が簡単です...

(GCDを使用して、それがどのように見えるかを確認することもしました:

dispatch_queue_t q = dispatch_queue_create( NULL, NULL ) ;
dispatch_async( q, ^{
    NSDate * when = [ NSDate date ] ;

    for ( int battery = 1000; battery >= 0; battery -= 1 )
    {
        dispatch_sync( dispatch_get_main_queue(), ^{
            [batteryLevel setProgress:(CGFloat)battery / 10.0 animated:YES];
            batteryLevelLabel.text = [NSString stringWithFormat:@"Battery Level: %f%%", (CGFloat)battery / 10.0 ];
        }) ;

        when = [ NSDate dateWithTimeInterval:1.0 sinceDate:when ] ;
        [ NSThread sleepUntilDate:when ] ;
    }
}) ;

(しかし、異なるキューが異なるスレッドにあることが保証されているとは思いません)

于 2014-02-15T20:09:31.823 に答える
0

提案どおりにnstimerを試してください

[NSTimer scheduledTimerWithTimeInterval:9.0
target:self
selector:@selector(targetMethod:)
userInfo:nil
repeats:YES];

//targetMethod は 9 秒ごとに呼び出され [myTimer invalidate]; myTimer = nil;ます //タスクが完了すると呼び出されます

于 2014-02-15T18:17:34.907 に答える
-1

使えます+ (void)sleepUntilDate:(NSDate *)aDate

于 2014-02-15T18:12:33.400 に答える