即使显示不刷新,CADisplaylink代码也会触发

时间:2013-06-10 15:55:22

标签: cadisplaylink

注意:从iOS7开始,此问题可能仅在模拟器中显示 - 仍在测试中。

我有一个CADisplayLink的实现,当且仅当显示实际刷新时我需要运行代码

这不会发生。

这是一个非常简单的测试程序:

我启动显示链接运行;在第一帧中,aLabel应显示" WordFlash&#34 ;;对于接下来的19帧,它应该显示" --------"对于接下来的100,它应该是空白的;然后循环应该重复。

偶尔(比如8次中的1次),并且不可预测地,屏幕不会刷新以显示" WordFlash"虽然代码确实被解雇了(因为计数器已经提前)。我需要计数器只有在" WordFlash"已成功显示正好1帧。

有什么想法吗?我完全难过了。

注意:这种显示 - 刷新 - 跳过似乎与设备执行简单代码所花费的时间无关(因为在NSLogged执行时间中,代码在两个不同的循环中可以是相同的,而只有一个周期已经成功地闪现了这个词。

    #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'/ P>

2 个答案:

答案 0 :(得分:1)

如果我猜测,我会说在屏幕刷新时动画UILabel不是最好的做事方式。根据我的经验,更改它们上的文本可能需要一些时间来渲染。如果您想在屏幕上画一个短划线,可以通过使用Core Graphics API或基于CALayer的绘图方法来提供更好的服务。

答案 1 :(得分:0)

您的displaySensitiveProcedure可能需要多个帧(16.7ms)来更新屏幕,这使得它跳过一帧。如果你持续采用更多(例如20ms),你可以减少DisplayLink的频率,以较慢的帧率获得平滑的动画 - 请参阅frameInterval属性。我建议通过这样做来计时你的回调:

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

  ... <code> ...

  CFTimeInterval endTime = CACurrentMediaTime();
  NSLog(@"frame time: %f", endTime - startTime);
}