在使用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()