iOS内存增加问题

时间:2015-01-07 20:55:02

标签: ios http core-data swift memory-management

我正在iOS中的后台线程上提交构建的JSON数据,并且在运行时我看到内存在这里呈指数级上升,最终导致崩溃。我已经多次浏览过这段代码,并且无法弄清楚为什么内存会上升,因为看起来每次迭代都会释放所有内容。

它的作用是从Core Data中实现的队列中提取记录,并且每32个队列都向该服务器提交一个HTTP PUT请求。在每次迭代之后,它会删除这些记录并保存上下文。

编辑:测试后我发现它是HTTP的一部分。我仍然无法分辨是什么导致了这种情况并且增加了内存。可能有太多单独的连接?

以下是代码:

class func startSubmitting()
{
    // If this has already been called then don't go back into it
    if submitThreadRunning
    {
        return
    }

    var mainQueue:NSOperationQueue = NSOperationQueue()

    mainQueue.addOperationWithBlock(
    {
        let url: String = "URL_HERE"

        let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        let managedContext = NSManagedObjectContext()
        managedContext.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator

        submitThreadRunning = true

        var offSetCount = 0

        var fetchRequest = NSFetchRequest(entityName:"Queue")
        var error: NSError?

        var sortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false)
        fetchRequest.sortDescriptors?.append(sortDescriptor)

        // Limit to 32 records at a time
        fetchRequest.fetchLimit = 32
        fetchRequest.fetchOffset = offSetCount

        while submitThreadRunning
        {
            if let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [Queue]
            {
                // If no fetched results, sleep for a bit so as to not hammer the battery life
                if fetchedResults.count == 0
                {
                    NSThread.sleepForTimeInterval(5.0)
                    continue
                }

                var counter = 0
                var data = String(format:"{\"apiKey\": \"%@\", \"data\":[", apiKey!)

                for result in fetchedResults
                {
                    if submitThreadRunning
                    {
                        let count = fetchedResults.count

                        if fetchedResults.count != (counter + 1)
                        {
                            data += result.json + ","

                            // Remove the record
                            managedContext.deleteObject(result)

                            // Update the counter
                            counter++

                            // Update the offset
                            offSetCount++

                            continue
                        }
                        else
                        {
                            data += result.json + "]}"
                        }
                    }
                    else
                    {
                        // We are stopping so go ahead and finish off the array and continue
                        data += result.json + "]}"
                    }

                    var request: NSMutableURLRequest = NSMutableURLRequest()
                    var response: NSURLResponse?

                    request.URL = NSURL(string: url)
                    request.HTTPMethod = "PUT"
                    request.setValue("application/json", forHTTPHeaderField: "Accept")
                    request.setValue("application/json", forHTTPHeaderField: "Content-Type")

                    request.HTTPBody = (data as NSString).dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)

                    NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)

                    let statusCode = (response as NSHTTPURLResponse).statusCode

                    // Handle any errors
                    if error != nil || statusCode >= 400
                    {
                        // Undo all changes to the data store from this iteration
                        for var i = 0; i < counter - 1; i++
                        {
                            managedContext.undo()
                        }

                        // Update the offest
                        offSetCount++

                        continue
                    }

                    // Remove the record
                    managedContext.deleteObject(result)

                    // Update the offest
                    offSetCount++
                }
            }

            // Save all changes to the data store
            managedContext.save(&error)

            if error != nil
            {
                // TODO Show an error message on the UI Thread
            }
        }
    })
}

1 个答案:

答案 0 :(得分:0)

找到解决方案here

它正在为所有HTTP请求和响应创建一个非常大的缓存,这就是Instruments显示已创建的6K +字符串的原因。所以,一旦我输入了这行代码,它就可以正常运行了,而且根本没有内存问题。这似乎是iOS所做的事情,并且在API文档中没有很好地记录。所以希望这会对其他人有所帮助。