2016-08-24 2 views
0

ich ein seltsames Verhalten in meinem Swift app habe, dass ich zur Zeit nicht verstehen.Jede 11. Ausführung von NSURLSessionTask dauert viel länger als andere

Ich habe subclassed NSOperation verschiedene Operationen zu erstellen, die Rest-WebServices über NSURLSession/NSURLSessionTask aufrufen können. Dies funktioniert im Allgemeinen gut.

In meinem Fall habe ich nacheinander viele dieser Operationen auszuführen. Nehmen wir an, ich erstelle eine "Kette" von 30 NSOperationen mit Einstellungsabhängigkeiten, um sie nacheinander auszuführen.

Nun konnte ich das Verhalten reproduzieren, dass jeder 11. (?!) Die Ausführung einer solchen Operation, dauert viel länger als die anderen. Es scheint, als ob die Ausführung fast 10 Sekunden lang "schläft", bevor es weitergeht. Ich kann ausschließen, dass der konkrete Web-Service-Aufruf das Problem ist. Denn wenn ich die Reihenfolge der Ausführung ändere, ist es immer noch die 11. Operation, die "hängt".

Derzeit bin ich die Schaffung einer neuen Instanz von NSURLSession (default) während der Ausführung jeder Operation. Gestern habe ich versucht, eine statische Instanz von NSURLSession zu erstellen und die Instanzen von NSURLSessionTask nur während der Ausführung zu erstellen. Und jetzt ist der "Aufhänger" weg! Leider konnte ich dies nicht tun, da NSURLSessionDelegate für einige Operationen anders sein muss, aber dieser Delegat muss während der Initialisierung übergeben werden.

Hat jemand ein ähnliches Problem auftreten?

Zuerst dachte ich, dass mein Code zu komplex ist, um zu posten. Aber nach Ketans Kommentar werde ich es versuchen. Ich habe es auf die wichtigsten Teile reduziert. Ich hoffe, dass dies hilft, mein Problem zu zeigen. Wenn Sie mehr Details benötigen, lassen Sie es mich wissen.

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

Fügen Sie Ihren Code hinzu, wie Sie das tun! – Lion

Antwort

0

Awww ... Ich habe vergessen, einfach session.finishTasksAndInvalidate() aufrufen, um die Sitzung nach meinem webService Aufruf erfolgt zu entkräften.

Das löst mein Problem!

Verwandte Themen