我正在尝试创建一个加载屏幕,在我的应用程序发出网络请求时绘制一个圆圈。圈的数量意味着表示请求的完成程度。但是,网络请求和动画之间存在严重的延迟(约8秒)。经过大量的搜索之后,我还没有发现任何有过这个问题的人,所以我非常绝望。CAShapeLayer路径动画有严重延迟
我现在的设置是,一个NSProgress对象会随着请求被更新而更新,并且会触发userInfo中NSProgress对象的KVO通知。这与here发现的方法相同。
#Client.m
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
NSProgress *progress = (NSProgress *)object;
NSDictionary *userInfo = @{@"progress":progress};
[[NSNotificationCenter defaultCenter] postNotificationName:@"FractionCompleted" object:self userInfo:userInfo];
}
}
然后被监听通知将更新与NSProgress的fractionCompleted的LoadingProgressView视图控制器对象,它接收。现在
#MainViewController.m
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateProgress:) name:@"FractionCompleted" object:nil];
...
...
- (void)updateProgress:(NSNotification*)note {
NSProgress* prog = note.userInfo[@"progress"];
[self.progressIndicatorView updateProgress:(CGFloat)prog.fractionCompleted];
}
的LoadingProgressView内,该CAShapeLayer的strokeEnd属性设置为fractionCompleted值。我正在使用来自发现here的教程的相同想法。
#LoadingProgressView.m
- (void)updateProgress:(CGFloat)frac {
_circlePathLayer.strokeEnd = frac;
}
当我实际发出请求时,在请求完成后大约5秒后没有任何反应。在那一刻,整个圆圈就会立即生成动画。
我绝对没有想法为什么会发生这种情况,这让我发疯。我可以清楚地看到使用调试器实时更新strokeEnd属性,然而LoadingProgressView拒绝重新渲染,直到很久以后。很感谢任何形式的帮助。谢谢。
编辑:好的,所以临时解决方案是推迟一个新的线程延迟0更新每个通知的进度视图。然而,这似乎是可怜的线程管理,因为我可以创建超过一百个不同的线程来完成相同的任务。我想知道是否还有其他事情可以做。
- (void)updateProgress:(NSNotification*)note {
NSProgress* prog = note.userInfo[@"progress"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.progressIndicatorView updateProgress:(CGFloat)prog.fractionCompleted];
});
}
'dispatch_after'不会创建(或'fork')一个新的线程 - 它只是在指定的队列上运行一个块。传递'dispatch_get_main_queue()'将在主线程中有效地运行该块。 – Losiowaty
此外,从主线程更新外界的UI是不会工作的:) – Losiowaty
哈哈哦,好的谢谢你的信息。你介意解释这里发生了什么,为什么我必须首先做这件事? – blzn