32416


CoreDataのinsert時のオブジェクトの解放方法を教えてください。  
例えば、エンティティーpin, ponとの関係を１対多として、ArrangementをOrderedにします。  
サンプルコードではpinに対してponを100件づつ生成しsava()しています。  
save()後にcontextをreset()し、このタイミングでオブジェクトは解放されることを期待していますが、解放できていないようです。

オブジェクトが解放されないとinsert可能なデータ量はストレージサイズより極小のメモリサイズの制限を受けてしまいます。

コードの不備などありましたら教えてください。

(CoreData model)

[code]

    Entities:
     Entity|Attribute|Type
     ======+=========+======
     Pin   |name     |String
     Pon   |name     |String
    
    Relationships:
     Entity|Relationship|Destination|inverse|type   |Arrangement
     ======+============+===========+=======+=======+===========
     Pin   |Pons        |Pon        |pin    |To Many|Ordered
     Pon   |pin         |pin        |pons   |To One |-
    
[/code]

(code)

[code]

    [AppDelegate.swift]
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        for i in 0..<10 {
            let pin = NSEntityDescription.insertNewObject(forEntityName: "Pin", into: managedObjectContext) as! Pin
            pin.name = "pin\(i)"
            for j in 0..<100 {
                let pon = NSEntityDescription.insertNewObject(forEntityName: "Pon", into: managedObjectContext) as! Pon
                pon.name = "pon\(j)"
                pon.pin = pin
            }
    
            if managedObjectContext.hasChanges {
                do {
                    try managedObjectContext.save()
                } catch {
                    let nserror = error as NSError
                    NSApplication.shared().presentError(nserror)
                }
             }
    
             managedObjectContext.reset()
             // ここでpin, ponが解放されていて欲しいのだけど...
        }
    
        NSLog("breakpoint")  // ここにbreakpointを設定して Xcode8のMemory Graphを見るとオブジェクトPonが1,000件残ってる。
    
    }
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/Fjuks.png)](https://i.stack.imgur.com/Fjuks.png)


CC BY-SA 3.0
2017-02-05T15:00:24.367
32407
2017-02-06T02:57:41.893
2017-02-06T02:57:41.893
76
20521
question
swift swift3 coredata
CoreDataのinsert時のオブジェクトの解放方法を教えてください


まず、オブジェクトそのものを解放させるために`autoreleasepool`で囲みます。コードを見る限り、内側のループで作成されたオブジェクトを、それぞれのループごとに解放させたいようですので、内側のループを`autoreleasepool`で囲みます。  
そのあと、`NSManagedObjectContext.reset()`ではなく、`refreshAllObjects()`を呼びます。

[code]

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        for i in 0..<10 {
            autoreleasepool { (result) in
                let pin = NSEntityDescription.insertNewObject(forEntityName: "Pin", into: managedObjectContext) as! Pin
                pin.name = "pin\(i)"
                for j in 0..<100 {
                    let pon = NSEntityDescription.insertNewObject(forEntityName: "Pon", into: managedObjectContext) as! Pon
                    pon.name = "pon\(j)"
                    pon.pin = pin
                }
    
                if managedObjectContext.hasChanges {
                    do {
                        try managedObjectContext.save()
                    } catch {
                        let nserror = error as NSError
                        NSApplication.shared().presentError(nserror)
                    }
                }
            }
            managedObjectContext.refreshAllObjects()
        }
    
        NSLog("breakpoint")  // ここにbreakpointを設定して Xcode8のMemory Graphを見るとオブジェクトPonが1,000件残ってる。
    }
    
[/code]


CC BY-SA 3.0
2017-02-06T00:19:25.880
32416
2017-02-06T00:19:25.880
5519
32407
answer