在Swift中的HTTP长轮询

7

我正在尝试使用iOS 8+中的Swift实现长轮询解决方案。

虽然该解决方案无疑有效,并且可以使主线程为空闲以进行UI交互,但内存使用不断增加,因此显然我做错了什么。我编写的类如下:

enum LongPollError:ErrorType{
    case IncorrectlyFormattedUrl
    case HttpError
}

public class LongPollingRequest: NSObject {
    var GlobalUserInitiatedQueue: dispatch_queue_t {
        return dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)
    }

    var GlobalBackgroundQueue: dispatch_queue_t {
        return dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.rawValue), 0)
    }

    var longPollDelegate: LongPollingDelegate
    var request: NSURLRequest?

    init(delegate:LongPollingDelegate){
        longPollDelegate = delegate
    }

    public func poll(endpointUrl:String) throws -> Void{
        let url = NSURL(string: endpointUrl)
        if(url == nil){
            throw LongPollError.IncorrectlyFormattedUrl
        }
        request = NSURLRequest(URL: url!)
        poll()
    }

    private func poll(){
        dispatch_async(GlobalBackgroundQueue) {
            self.longPoll()
        }
    }

    private func longPoll() -> Void{
        autoreleasepool{
            do{
                let urlSession = NSURLSession.sharedSession()
                let dataTask = urlSession.dataTaskWithRequest(self.request!, completionHandler: {
                    (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
                    if( error == nil ) {
                        self.longPollDelegate.dataReceived(data)
                        self.poll()
                    } else {
                        self.longPollDelegate.errorReceived()
                    }
                })
                dataTask.resume()
            }
        }
    }
}

我尝试使用Instruments对应用程序进行分析,但结果很令人困惑。希望有人可以指点我正确的方向。

谢谢


1
LongPollDelegate很强大,所以你可能有一个保留循环。尝试将其设置为weak。 - David H
很明显,长时间进行HTTP轮询会导致内存使用量增加...显然不是一个好主意...因此,套接字编程的魔力就出现了...看看套接字编程或选择一些API,比如Pusher。 - LC 웃
2
感谢您的评论@anishparajuli,但为什么这很明显呢?从上面的代码示例中,您会将引起内存占用增加的原因归因于哪里?重复的操作并不一定意味着增加的内存使用量(我认为David H已经强调了这个问题)。我同意套接字方面的观点,但无法理解Pusher这样的API与此的任何相关性 - 您能否详细说明一下?谢谢。 - JordanMazurke
如果涉及到内存问题,你需要将LongPollDelegate声明为weak类型。考虑到API轮询会持续使用CPU资源,因此使用套接字优化请求方式,以一个单一数据包的形式向服务器请求,而不是进行HTTP请求。 - LC 웃
2
@DavidH - 你是对的。问题已解决 - 你想发表一个答案,这样我就可以标记为正确吗?另外,请注意不要过于关注Xcode内存监视器 - 始终使用Instruments。 - JordanMazurke
你介意分享整个代码(与示例相关)吗?对于这样的场景,它似乎是一个非常好的模型。谢谢! - amok
1个回答

3

LongPollDelegate很强大,所以你可能会出现保留周期。将其变为弱变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接