【发布时间】:2015-01-07 20:55:02
【问题描述】:
我正在 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
}
}
})
}
【问题讨论】:
-
“重现的最短代码”是关闭原因的相关位。请将其缩减为具有相同问题的较小程序。
-
你确定
error是nil? -
使用工具,卢克。
-
经过进一步测试,我发现当我取出HTTP代码时,内存并没有增加。有人知道吗?
-
哦,已经这样做了,这是一大堆可变字符串,这就是我感到困惑的原因。应该在上面的帖子中说明这一点。
标签: ios http core-data swift memory-management