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