【问题标题】:Fixing my network activity indicator修复我的网络活动指示器
【发布时间】:2013-05-01 11:35:42
【问题描述】:

我的网络活动指示器有问题,有时它会在不应该显示的时候继续显示。

我为它编写了自己的经理,然后将其换成使用这样的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 运行,该 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 指出在某些地方这种情况不正常。

会不会是从多个线程运行这个函数会导致问题?我该如何解决这个问题?

【问题讨论】:

标签: ios objective-c network-programming nsoperation nsoperationqueue


【解决方案1】:

整数增量或减量不是线程安全的(据我所知),因此如果两个线程“同时”调用您的方法,则计数可能无法正确更新。

一种解决方案是添加一些同步指令(例如@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)];
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多