我正在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
}
}
})
}
答案 0 :(得分:0)
找到解决方案here。
它正在为所有HTTP请求和响应创建一个非常大的缓存,这就是Instruments显示已创建的6K +字符串的原因。所以,一旦我输入了这行代码,它就可以正常运行了,而且根本没有内存问题。这似乎是iOS所做的事情,并且在API文档中没有很好地记录。所以希望这会对其他人有所帮助。