3

我的網絡活動指示器出現問題,有時會在不應該顯示時繼續顯示。修復我的網絡活動指示器

我寫我自己的經理,並換出來的一個使用的NSAssert聲明是這樣的...

- (void)setNetworkActivityIndicatorVisible:(BOOL)setVisible { 
    static NSInteger NumberOfCallsToSetVisible = 0; 
    if (setVisible) 
     NumberOfCallsToSetVisible++; 
    else 
     NumberOfCallsToSetVisible--; 

    // The assertion helps to find programmer errors in activity indicator management. 
    // Since a negative NumberOfCallsToSetVisible is not a fatal error, 
    // it should probably be removed from production code. 
    NSAssert(NumberOfCallsToSetVisible >= 0, @"Network Activity Indicator was asked to hide more often than shown"); 

    // Display the indicator as long as our static counter is > 0. 
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:(NumberOfCallsToSetVisible > 0)]; 
} 

我發現它SO,它已立即指出,事情錯了與我使用這個功能。

我所有的網絡活動都是通過一個單獨的NSOperationQueue來運行的,它由單例類管理。每個操作都是NSOperation的子類(實際上是TemplateOperation的一個子類,它是NSOperation的子類)。

反正,所有的下載和上傳工作正常,我做的所有這些像這樣...

- (void)sendRequest:(NSURLRequest *)request 
{ 
    NSError *error = nil; 
    NSURLResponse *response = nil; 

    [[NetworkManager sharedInstance] setNetworkActivityIndicatorVisible:YES]; 
    NSData *data = [NSURLConnection sendSynchronousRequest:request 
             returningResponse:&response 
                error:&error]; 
    [[NetworkManager sharedInstance] setNetworkActivityIndicatorVisible:NO]; 

    // other stuff... 

    [self processData:data]; 
} 

重要的線是之前和之後我發送NSURLConnection同步。

在發送請求之前,我立即將網絡活動指示器設置爲可見(使用我的管理員類),然後立即將其設置爲不可見。

除了NSAssert指出某處沒有正確地發生這種情況。

難道是從多個線程運行這個函數可能會導致一個問題?我怎麼能解決這個問題?

+1

這應該有助於https://github.com/rs/SDNetworkActivityIndi​​cator – Moxy 2013-05-07 13:52:30

+0

非常感謝!兩個很棒的答案:D – Fogmeister 2013-05-07 13:57:02

回答

7

整數遞增或遞減不是線程安全的(據我所知),所以如果兩個線程同時調用你的方法,計數可能無法正確更新。

一個解決方案是將一些同步指令(如@synchronized) 添加到您的方法。或者你用原子遞增/遞減功能:

#include <libkern/OSAtomic.h> 

- (void)setNetworkActivityIndicatorVisible:(BOOL)setVisible { 
    static volatile int32_t NumberOfCallsToSetVisible = 0; 
    int32_t newValue = OSAtomicAdd32((setVisible ? +1 : -1), &NumberOfCallsToSetVisible); 

    NSAssert(newValue >= 0, @"Network Activity Indicator was asked to hide more often than shown"); 
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:(newValue > 0)]; 
} 
+0

非常好,非常感謝。 – Fogmeister 2013-05-07 13:55:46

+0

@Fogmeister:請看看http://stackoverflow.com/questions/17176190/objective-c-thread-safe-counter/17177772#17177772關於我的回答中的缺陷:-) – 2013-06-18 20:08:57