2

注: iOS7 の時点では、この問題はシミュレーターでのみ発生する可能性があります。まだテスト中です。

CADisplayLink の実装があり、表示が実際に更新された場合にのみコードを実行する必要があります

これは起こりません。

以下は、非常に単純なテスト プログラムです。

表示リンクの実行を開始します。最初のフレームで、aLabel は「WordFlash」を表示する必要があります。次の 19 フレームでは "--------" を表示し、次の 100 フレームでは空白にする必要があります。その後、サイクルが繰り返されます。

ときどき (たとえば 8 回に 1 回)、予期せずに、コードが実際に実行されても (カウンターが進んだため)、画面が更新されずに「WordFlash」が表示されません。「WordFlash」が正確に 1 フレームだけ正常に表示された場合にのみ、カウンタを進める必要があります。

何か案は?私は完全に困惑しています。

注: この表示リフレッシュ スキップは、デバイスが単純なコードを実行するのにかかる時間と相関関係なく発生するようです (NSLogged 実行時間のように、コードは 2 つの異なるサイクルで同一である可能性がありますが、1 つのサイクルのみが正常に実行されます。という言葉をひらめいた。

    #import "HomePwnerViewController.h"


@interface HomePwnerViewController ()

@end

@implementation HomePwnerViewController {
    int counter;
    UILabel *aLabel;

}

- (void)viewDidLoad
{
    [super viewDidLoad];

    aLabel = [[UILabel alloc] initWithFrame:self.view.frame];

    [self.view addSubview:aLabel];

    aLabel.alpha = 1;

    aLabel.text = @"";

    aLabel.textAlignment = NSTextAlignmentCenter;

    [aLabel setFont:[UIFont fontWithName:@"Courier" size:50]];

  [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(testWordFlashMethod) userInfo:nil repeats:NO];

}

- (void) displaySensitiveProcedure: (CADisplayLink *) sender {

    CFTimeInterval startTime = CACurrentMediaTime();


    if (counter == 0)
        aLabel.text = @"FlashWord";
    else if (counter < 20)
        aLabel.text = @"---------";
    else
        aLabel.text = @"";

    CFTimeInterval endTime = CACurrentMediaTime();
    if (counter == 0)
        NSLog(@"frame time %f frame length %f ratio %f", endTime - startTime, sender.duration, (endTime - startTime)/sender.duration);

    counter++;

    if (counter == 120)
        counter = 0;
}

- (void) testWordFlashMethod {
    CADisplayLink *DL = [CADisplayLink displayLinkWithTarget:self selector:@selector(displaySensitiveProcedure:)];

    DL.frameInterval = 1;

    counter = 0;

    [DL addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];   
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

とても感謝しております、

b

4

2 に答える 2

1

推測すると、画面の更新時に UILabel をアニメーション化することは、最善の方法ではありません。私の経験では、それらのテキストを変更すると、レンダリングに少し時間がかかる場合があります。画面全体にダッシュを描画したい場合は、Core Graphics API を使用するか、CALayer ベースの描画アプローチを使用すると、より適切に処理できる場合があります。

于 2013-06-10T22:40:04.280 に答える
0

displaySensitiveProcedure は、画面を更新するのに 1 フレーム (16.7 ミリ秒) 以上かかる可能性があり、フレームをスキップします。一貫してそれ以上 (たとえば 20 ミリ秒) かかる場合は、DisplayLink の起動頻度を減らして、より遅いフレームレートでスムーズなアニメーションを取得できます。frameInterval プロパティを参照してください。次のようにして、コールバックのタイミングを調整することをお勧めします。

- (void) displaySensitiveProcedure: (CADisplayLink *) sender { 
  CFTimeInterval startTime = CACurrentMediaTime();

  ... <code> ...

  CFTimeInterval endTime = CACurrentMediaTime();
  NSLog(@"frame time: %f", endTime - startTime);
}
于 2013-06-12T18:36:18.097 に答える