2

我发现有时你可能会在你的 iPhone 应用程序中做一些需要用户等待它完成的事情。通常这是与网络相关的活动,但在其他情况下可能不是。就我而言,我正在解析来自网络连接的响应,并希望网络活动指示器即使已经下载了内容也能继续旋转。

以下是我正在做的事情:

applicationDelegate.m:

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

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

其他视图.m:

dispatch_queue_t dataLoadingQueue = dispatch_queue_create("synchronise", NULL);
    dispatch_async(dataLoadingQueue,
                   ^{
                       [appDelegate setNetworkActivityIndicatorVisible:YES];
                       [[DataLoader instance]LoadDataForGrewal];
                       [[FieldConsultantViewModelManager instance] resetCache];  
                       [[DailyFieldConsultantViewModelManager instance] clearCache];
                       [appDelegate loadMainViews];
                       [[DataLoader instance]LoadDataForOtherEntities]; 
                       [appDelegate setNetworkActivityIndicatorVisible:NO];
                   });    
 dispatch_release(dataLoadingQueue);

正如您在上面看到的,我试图在将数据更新到数据库时保留网络指示器,但它不起作用,有什么线索/建议吗?

谢谢 编辑:

dispatch_queue_t dataLoadingQueue = dispatch_queue_create("synchronise", NULL);
    dispatch_async(dataLoadingQueue,
                   ^{
                       dispatch_async(dispatch_get_main_queue(), ^{ [self setNetworkActivityIndicatorVisible:YES]; });
                       [[DataLoader instance]LoadDataForGrewal];
                       [[FieldConsultantViewModelManager instance] resetCache];  
                       [[DailyFieldConsultantViewModelManager instance] clearCache];
                       [appDelegate loadMainViews];
                       [[DataLoader instance]LoadDataForOtherEntities]; 
                       dispatch_async(dispatch_get_main_queue(), ^{ [self setNetworkActivityIndicatorVisible:NO]; });
                   });    
 dispatch_release(dataLoadingQueue);

它不起作用我不知道为什么,因为我是 ios 的新手

4

2 回答 2

2

尝试setNetworkActivityIndicatorVisible:在主队列上调度您的呼叫,因为 UIApplication 在 UIKit 中并且 UIKit 不是线程安全的。

于 2012-07-19T15:09:54.797 回答
1

对于任何寻求完整解决方案的人,这就是我使用的(在Swift中)。停止网络指示器时会延迟一小段时间。如果您有大量串行网络请求,这将防止指示灯闪烁。

private var networkActivityCount = 0

func updateNetworkActivityCount(increaseNumber increase:Bool)
{
    let appendingCount = increase ? 1 : -1
    networkActivityCount += appendingCount
    let delayInSeconds = increase ? 0.0 : 0.7
    perform({ () -> () in
        let application = UIApplication.sharedApplication()
        let shouldBeVisible = self.networkActivityCount > 0
        if application.networkActivityIndicatorVisible != shouldBeVisible {
            application.networkActivityIndicatorVisible = shouldBeVisible
        }
    }, afterDelay: delayInSeconds)
}

其中perform:afterDelay定义为

public func perform(block: ()->(), afterDelay:Double) {
    let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(afterDelay * Double(NSEC_PER_SEC)))
    dispatch_after(dispatchTime, dispatch_get_main_queue(), {
         block()
    })
}

只需updateNetworkActivityCount(increaseNumber: true)在您的请求之前调用,并false在您的请求回调中调用。IE:

updateNetworkActivityCount(increaseNumber: true)
let task = urlSession.dataTaskWithRequest(request) { data, response, error in
    self.updateNetworkActivityCount(increaseNumber: false)
    ...
于 2016-03-08T16:05:15.420 回答