我的Swift应用程序中有一个奇怪的行为,我目前不明白。
我已经将NSOperation子类化为创建可以通过NSURLSession / NSURLSessionTask调用Rest-WebServices的不同操作。这一般工作正常。
在我的情况下,我必须连续执行许多这些操作。假设我创建了一个包含30个NSOperations的“链”,并设置依赖关系来逐个执行它们。
现在我可以重现这种行为,这种操作的每第11次(?!)执行所花费的时间比其他操作要长得多。在执行之前,似乎执行“睡眠”了将近10秒。我可以排除,具体的Web服务调用是问题。因为如果我改变执行顺序,它仍然是“挂起”的第11个操作。
目前,我正在执行每个操作期间创建一个新的NSURLSession实例(defaultConfiguration)。昨天我尝试创建NSURLSession的静态实例,并仅在执行期间创建NSURLSessionTask的实例。现在,“衣架”消失了!不幸的是我不能这样做,因为NSURLSessionDelegate对于某些操作必须是不同的,但是这个委托必须在初始化期间传递。
有没有人遇到类似的行为?
首先我认为我的代码太复杂而无法发布。但在Ketans评论之后,我会试一试。我把它修剪成最重要的部分。我希望这有助于显示我的问题。如果您需要更多细节,请告诉我。
class AbstractWebServiceOperation: NSOperation {
// VARIANT 2: Create a static NSURLSession only once --> The "sleep" DOES NOT occur!
static let SESSION = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
init(servicePath:String, httpMethod:String) {
// This is an 'abstract' class, that will be subclassed for concrete webService calls that differ in servicePath for URL, HTTP Method and parameters
}
// Override start() function of NSOperation to do webService call. NSOperations vars (ready, executing, finished) are overridden too, to get NSOperation "waiting" for the webService result. But I don't think it is relevant for the issue. So I did leave it out.
override func start() {
super.start()
// [...]
if let request = createRequest()
{
let task = createTask(request)
task.resume()
}
// [...]
}
// Creates the concrete NSURLRequest by using the service path and HTTP method defined by the concrete subclass.
private func createRequest()-> NSMutableURLRequest? {
// [...]
let webServiceURL = "https://\(self.servicePath)"
let url = NSURL(string: webServiceURL)
let request = NSMutableURLRequest(URL: url!)
request.timeoutInterval = 60
request.HTTPMethod = self.httpMethod
request.addValue("application/json;charset=UTF-8", forHTTPHeaderField: "Content-Type")
request.addValue("application/json;charset=UTF-8", forHTTPHeaderField: "Accept")
return request;
}
// Creates the concrete NSURLSessionTask for the given NSURLRequest (using a completionHandler defined by getCompletionHandler())
func createTask(request:NSURLRequest) -> NSURLSessionTask
{
// VARIANT 1: Create a new NSURLSession every time a AbstractWebServiceOperation is executed --> The "sleep" occurs!
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
return session.dataTaskWithRequest(request, completionHandler:getCompletionHandler())
// VARIANT 2: Create a static NSURLSession only once --> The "sleep" DOES NOT occur!
return AbstractWebServiceOperation.SESSION.dataTaskWithRequest(request, completionHandler:getCompletionHandler())
}
// Returns the completion handler for the NSURLSessionTask (may be overriden in subclass)
func getCompletionHandler() -> (NSData?, NSURLResponse?, NSError?) -> Void
{
return completionHandler
}
// Default completion handler
lazy var completionHandler:(NSData?, NSURLResponse?, NSError?) -> Void = {(data : NSData?, response : NSURLResponse?, error : NSError?) in
// default completion handling
}
}
答案 0 :(得分:0)
Awww ...在我的webService调用完成后,我忘了调用session.finishTasksAndInvalidate()来使会话失效。
这解决了我的问题!