每次执行NSURLSessionTask的时间都要比其他时间长

时间:2016-08-24 04:41:47

标签: ios swift nsurlsession nsurlrequest

我的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
    }
}

1 个答案:

答案 0 :(得分:0)

Awww ...在我的webService调用完成后,我忘了调用session.finishTasksAndInvalidate()来使会话失效。

这解决了我的问题!