注意:从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>
答案 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);
}