2015-08-27 74 views
0

我正在嘗試創建一個加載屏幕,在我的應用程序發出網絡請求時繪製一個圓圈。圈的數量意味着表示請求的完成程度。但是,網絡請求和動畫之間存在嚴重的延遲(約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]; 
    }); 
} 
+0

'dispatch_after'不會創建(或'fork')一個新的線程 - 它只是在指定的隊列上運行一個塊。傳遞'dispatch_get_main_queue()'將在主線程中有效地運行該塊。 – Losiowaty

+0

此外,從主線程更新外界的UI是不會工作的:) – Losiowaty

+0

哈哈哦,好的謝謝你的信息。你介意解釋這裏發生了什麼,爲什麼我必須首先做這件事? – blzn

回答

1

我遇到了同樣的問題。這似乎是由後臺線程設置路徑引起的。確保主線程發生這種情況,解決了問題。現在更新形狀立即繪製。

+1

雖然這個答案看起來是正確的,或者至少在正確的軌道上,您能否提供更多的信息和一些代碼來澄清? – SomethingOn

+0

@ s1m0nw1:這不是一個不同的問題 – ExDev