NSURLSession性能 - 可能的竞争条件或被阻止的线程?

时间:2016-05-27 11:50:56

标签: ios swift thread-safety nsurlsession avkit

我的iOS应用程序遇到了一些性能问题,这是我第一次使用NSURLSession和NSURLRequest,尽管我已尽力通知自己,但我和#39;试图调试我面临的性能问题。

所以我得到了什么:我有一个用Swift 2编写的iOS 9应用程序,我通过Get与NodeJS / Express服务器进行通信,使用NSURLRequest和NSURLMutableRequest发布和发出Http请求。我发送请求以获取一组对象(总共不超过12000字节),但请求占用了大量时间(有时长达一分钟)。我已经将日志添加到nodeJs服务器,我可以看到请求的处理时间不超过30毫秒。

注意:我不确定这是否相关,但我使用单身"帮助"类来制作我的所有api请求和解析结果(保存身份验证令牌,解析JSON对象并将其保存到Core Data,将用户首选项保存到NSUserDefaults等),我使用单例,因此我可以静态访问它并且我正在解析所有数据不保存除服务器URL和NSURLSession之外的单例属性中的任何内容。

这是我的代码的样子。

//On initialization of the helper class
private let session = NSURLSession.sharedSession() 

func getAllObjects() {
    let route = "api/someRoute"
    let request = getRequest(route)
    request.timeoutInterval = httpTimeout
    session.dataTaskWithRequest(request, completionHandler: ResultingObjects).resume()
}
  

getRequest方法返回格式化的NSMutableURLRequest,如图所示   这里:

func getRequest(route: String) -> NSMutableURLRequest {
    let request = NSMutableURLRequest()
    request.URL = NSURL(string: "\(serverUrl)/\(route)")!
    request.HTTPMethod = "GET"
    request.addValue("Bearer \(self.AuthenticationToken()!)", forHTTPHeaderField: "Authorization")

    return request
}
  

完成处理程序将解析返回的对象并通知   带有结果解析对象的主线程,如下所示:

private func ResultingObjects(data: NSData?, response: NSURLResponse?, error: NSError?) {
    if let d = data {

        if !isAuthorized(d){
            return
        }
        do {
            if let JSON = try NSJSONSerialization.JSONObjectWithData(d, options: []) as? NSDictionary {

                if let message = JSON["message"] as? String {
                    if message == "Empty result" {
                        //- Return notification to be handled in main thread
                        notifyMainThread(NoObjectsFetched, payload: nil)
                        return
                    }
                }

                if let objcts = JSON["SomeObjects"] as? NSArray {
                    if let SomeObjects = parseResultingObjects(objcts) {
                        //- Return notification to be handled in main thread
                        notifyMainThread(ObjectsFetched, payload: ["payload": SomeObjects])
                    }
                    return
                }
            }
        }
        catch {
            print("Error getting resulting objects")
        }
    }
    else if let e = error {
        print("\(e), could not process GET request")
    }
}
  

我还尝试在主线程上解析生成的对象但是   这似乎没有什么区别。

     

如果您感到好奇,这就是我将数据发送到主线程的方式:

private func notifyMainThread(notification: String, payload: AnyObject?) {
    dispatch_async(dispatch_get_main_queue(), {
        if let p = payload {
            NSNotificationCenter.defaultCenter().postNotificationName(notification, object: nil,
                userInfo: p as! [String: [MYMODEL]])
        }
        else {
            NSNotificationCenter.defaultCenter().postNotificationName(notification, object: nil)
        }
    });
}

我发现了什么: 没有任何意义!我试过调试这个,但我不能确定问题是什么,当调试器遇到我的" getAllObjects"方法,它可能需要几秒钟(最多45秒)服务器记录它收到并处理请求(通常需要大约30毫秒)。据我所知,所有请求类型都会发生这种情况。此外,一旦应用程序返回数据(超快),解析它需要很长时间(大约4秒),而且它只有大约11kbs。

我还尝试更改请求缓存策略,以防应用程序通过服务器检查缓存记录的有效性,我使用了 ReloadIgnoringLocalAndRemoteCachedData ,它们都没有工作。

现在,这听起来像是内存泄漏 如果我在任何时候暂停应用程序(使用它几分钟后),我可以看到相关数量的线程。我老实说不太熟悉IOS,所以我不确定这些线程是来自模拟器还是属于应用程序,应用程序在AVPlayer类中流式传输视频内容(没有延迟问题)我相信很多这些主题与此有关,但我不确定这是否正常,这里是我的意思截图(注意滚动条T_T)Screenshot

可能是因为我有内存泄漏或某些僵尸线程会大大降低我应用的性能吗?唯一真正引人注意的延迟只发生在非常奇怪的HTTP请求上,我的UI中没有其他部分滞后,我的应用程序中没有其他功能遇到性能问题(甚至是来自网址的流媒体视频内容)。

描述此问题的最佳方法是指出问题的根源?

更新1: 感谢Scriptable的建议,我设法解决了线程问题(由多个AVPlayers做他们的事情引起)。然而,请求的性能没有得到解决。

值得指出的是,服务器实际上位于我发出请求的国家/地区,当从浏览器发出请求或形成命令行时,请求几乎是即时的。

此外,当我随机暂停应用程序时(我等待请求发生)我可以看到' mach_msg_trap'在某些主题中,我对此并不熟悉,但我相信这可能是竞争条件?还是僵局?

0 个答案:

没有答案