简体   繁体   English

修复我的网络活动指示器

[英]Fixing my network activity indicator

I have a problem with my network activity indicator in that sometimes it will continue to be displayed when it should not be. 我的网络活动指示器有问题,有时它会在不应该显示时继续显示。

I wrote my own manager for it and swapped it out for one that uses an NSAssert statement like this... 我为它编写了自己的经理并将其换成了一个使用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)];
}

I found it on SO and it has immediately pointed out that something is going wrong with my use of this function. 我在SO上发现了它,它立即指出我使用这个功能出了问题。

All of my network activity is exclusively run through a single NSOperationQueue which is managed by a singleton class. 我的所有网络活动都是通过一个由单例类管理的NSOperationQueue专门运行的。 Every operation is a subclass of NSOperation (actually a subclass of a TemplateOperation which is a subclass of NSOperation). 每个操作都是NSOperation的子类(实际上是TemplateOperation的子类,它是NSOperation的子类)。

Anyway, all the downloads and uploads are working fine and I'm doing them all like this... 无论如何,所有的下载和上传工作正常,我这样做就像这样......

- (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];
}

The important lines are immediately before and after I send the NSURLConnection synchronously. 重要的行是在我同步发送NSURLConnection之前和之后。

Immediately before I send the request I set the network activity indicator to visible (using my manager class) and then immediately after I set it back to invisible. 在我发送请求之前,我将网络活动指示器设置为可见(使用我的经理类),然后立即将其设置为不可见。

Except the NSAssert has pointed out that somewhere this is not happening properly. 除了NSAssert指出,某些地方这种情况没有发生。

Could it be that running this function from multiple threads could be causing an issue? 难道从多个线程运行此函数可能会导致问题吗? How could I solve this? 我该怎么解决这个问题?

Integer increment or decrement is not thread-safe (as far as I know), so if two threads call your method "simultaneously", the count might not get updated properly. 整数递增或递减不是线程安全的(据我所知),因此如果两个线程“同时”调用您的方法,则计数可能无法正确更新。

One solution would be to add some synchronization directive (such as @synchronized ) to your method. 一种解决方案是在方法中添加一些同步指令(例如@synchronized )。 Or you use the atomic increment/decrement functions: 或者您使用原子递增/递减函数:

#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)];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM