iOS:无法在NSURLSession委托内进行GUI更改



在使用NSURLSession委托时,我的iOS应用程序中的一些GUI组件出现问题。

我有一个UITableViewController,它向用户显示不同的地图区域。用户可以选择其中一个区域,我将推送一个新的UIViewController,显示有关该区域的一些详细信息。在UIViewController中,用户可以单击按钮下载此地图区域。

我使用NSURLSession下载地图。我有自己的方法来设置会话。

- (NSURLSession *)backgroundSession {
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.app"];

        sessionConfiguration.HTTPMaximumConnectionsPerHost = 2;
        session = [NSURLSession sessionWithConfiguration:sessionConfiguration
                                            delegate:self
                                       delegateQueue:nil];
    });
    return session;
}

我通过开始下载

self.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:hikingMap.downloadSource]];
[downloadTask resume];

这在我从UITableViewController打开的第一个区域上运行得很好。

示例:

1. Go to area A
2. Start downloading area A

然而,当我先看一些区域,然后转到另一个区域并尝试下载这个区域时,我的问题就出现了。

示例:

1. Go to area A
2. Go back to UITableViewController
3. Go to area B
4. Start downloading area B

实际下载运行良好。但是,一旦下载开始,我会对GUI进行一些更改。我隐藏了一些标签并显示了一些UIProgressViews。

我在下载进度的委托方法中做了这些更改:

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    dispatch_async(dispatch_get_main_queue(), ^{
         self.label.hidden = YES;
         self.progressView.hidden = NO;
    });
}

那些隐藏的更改没有反映在我的GUI中。基本上,我在委托方法之外对GUI所做的所有更改都很好,但在委托方法内部所做的任何更改都不起作用。

我不明白怎样才能解决这个问题。所以任何帮助都会很棒!告诉我,如果我需要添加更多的代码,让你了解发生了什么。

更新

我现在已经确认委托方法使用了对UIlabel的旧引用。我通过在打开区域A时更改标签文本进行测试,然后转到区域B进行下载时,我发现委托方法中的标签文本与区域A中的相同。

您的-(NSURLSession *)backgroundSession方法不安全。第二次调用它时,session变量设置为nil,并且没有正确初始化。尝试此修复

static NSURLSession *_sharedSession;
- (NSURLSession *)backgroundSession
{
  if (!_sharedSession)
  {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.app"];
        sessionConfiguration.HTTPMaximumConnectionsPerHost = 2;
        sharedSession = [NSURLSession sessionWithConfiguration:sessionConfiguration
                                            delegate:self
                                       delegateQueue:nil];
    });
  }
  return _sharedSession;
}

我在上传时遇到了同样的问题。

要克服它,您必须使共享会话(NSURLSession)无效并取消。在Swift中,您可以按以下方式进行操作:

session.invalidateAndCancel()

最新更新