Onde o NSManagedObjectContext deve ser criado?
Recentemente, aprendi sobre o Core Data e, especificamente, como fazer inserções com um grande número de objetos. Depois de aprender como fazer isso e resolver um problema de vazamento de memória que conheci, escrevi as perguntas e respostasVazamento de memória com inserção em lote de grandes dados Core no Swift.
Depois de mudarNSManagedObjectContext
de uma propriedade de classe para uma variável local e também salvando inserções em lotes, em vez de uma por vez, funcionou muito melhor. O problema de memória desapareceu e a velocidade melhorou.
O código que publiquei na minha resposta foi
let batchSize = 1000
// do some sort of loop for each batch of data to insert
while (thereAreStillMoreObjectsToAdd) {
// get the Managed Object Context
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
managedObjectContext.undoManager = nil // if you don't need to undo anything
// get the next 1000 or so data items that you want to insert
let array = nextBatch(batchSize) // your own implementation
// insert everything in this batch
for item in array {
// parse the array item or do whatever you need to get the entity attributes for the new object you are going to insert
// ...
// insert the new object
let newObject = NSEntityDescription.insertNewObjectForEntityForName("MyEntity", inManagedObjectContext: managedObjectContext) as! MyManagedObject
newObject.attribute1 = item.whatever
newObject.attribute2 = item.whoever
newObject.attribute3 = item.whenever
}
// save the context
do {
try managedObjectContext.save()
} catch {
print(error)
}
}
Este método parece estar funcionando bem para mim. A razão pela qual estou fazendo uma pergunta aqui, no entanto, é que duas pessoas (que sabem muito mais sobre iOS do que eu) fizeram comentários que eu não entendo.
Parece que no seu código você está usando o mesmo contexto de objeto gerenciado, não um novo.
... a implementação "usual" é uma propriedade lenta que cria o contexto uma vez durante a vida útil do aplicativo. Nesse caso, você está reutilizando o mesmo contexto que Mundi disse.
Agora eu não entendo. Eles estão dizendo que eusou usando o mesmo contexto de objeto gerenciado ou Idevemos usar o mesmo contexto de objeto gerenciado? Se eusou usando o mesmo, como é que eu crio um novo em cadawhile
ciclo? Ou se eudevemos usando apenas um contexto global, como faço sem causar vazamento de memória?
Anteriormente, eu havia declarado o contexto no meu View Controller, inicializado emviewDidLoad
, passou como parâmetro para minha classe de utilitários fazendo as inserções e apenas o utilizou para tudo. Depois de descobrir o grande vazamento de memória, comecei a criar o contexto localmente.
Uma das outras razões pelas quais comecei a criar os contextos localmente é porque odocumentação disse:
Primeiro, você normalmente deve criar um contexto de objeto gerenciado separado para a importação e definir seu gerenciador de desfazer como nulo. (Os contextos não são particularmente caros de criar; portanto, se você armazenar em cache seu coordenador persistente de loja, poderá usar contextos diferentes para diferentes conjuntos de trabalho ou operações distintas.)
Qual é a maneira padrão de usarNSManagedObjectContext
?