다음 예제에서 관련 개체가 원본/호스트 개체 할당이 해제 될 때 자동으로 할당이 해제되지 않는 이유를 설명 할 수 있기를 바랍니다. 아래의 예제 코드는 다소 (사전 사과)이지만 내 문제점을 설명합니다.NSManagedObjectContext 할당 해제 문제 - (Swift | Associated Objects)
import UIKit
import CoreData
class ViewController: UIViewController {
@IBAction func createProduct(sender: AnyObject) {
let context = CoreDataHelpers.vendBackgroundWorkerContext()
let newProduct = CoreDataHelpers.newProduct(context: context)
newProduct.sku = "8-084220001"
do {
try newProduct.managedObjectContext?.save()
print("Product created [SKU: \(newProduct.sku ?? "NotDefined")]")
} catch {
print(error)
}
}
}
public class CoreDataHelpers {
public static let mainContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
public class func vendBackgroundWorkerContext() -> NSManagedObjectContext {
let managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
managedObjectContext.parentContext = self.mainContext
return managedObjectContext
}
class func newProduct(context context: NSManagedObjectContext) -> Product {
let newProduct = NSEntityDescription.insertNewObjectForEntityForName("Product", inManagedObjectContext: context) as! Product
return newProduct
}
}
createProduct
기능이 실행되는 새로운 PrivateQueueConcurrencyType 관리 개체 컨텍스트 :
예는 문자열 속성 sku
와 엑스 코드 템플릿에서 제공하는 기본 CoreData의 스택과 함께 CoreData 엔터티 Product
가정 (MOC)는 새로운 Product
Managed Object (MO)에 의해 판매되고 사용됩니다. 위의 코드는 올바르게 작동합니다.
그러나! 나는 createProduct
함수의 처음 두 행을 결합하면 있도록 :
let newProduct = CoreDataHelpers.newProduct(context: CoreDataHelpers.vendBackgroundWorkerContext())
다음 응용 프로그램은
EXC_BAD_ACCESS
로
try newProduct.managedObjectContext?.save()
에서 충돌합니다.
언뜻보기에 이것은 약간 이상하게 보입니다. 우리가 한 것은 코드를 리팩토링 한 것입니다. documentation을 파기하면 managedObjectContext
속성은 unowned(unsafe)
으로 선언됩니다. 이것은 아마도 생성 된 MOC가 할당 해제되었음을 의미하며 매달 포인터 (제 가정이 틀린 경우 제발 수정하십시오)을 의미합니다.
MOC가 할당 해제되지 않도록하기 위해 MO 자체와 연결해 보았습니다. newProduct
:
class func newProduct(context context: NSManagedObjectContext) -> Product {
let newProduct = NSEntityDescription.insertNewObjectForEntityForName("Product", inManagedObjectContext: context) as! Product
var key: UInt8 = 0
objc_setAssociatedObject(newProduct, &key, context, .OBJC_ASSOCIATION_RETAIN)
return newProduct
}
이가 나타납니다 훌륭하게 작동 - 나는 악기에서 확인 될 때까지. (소스 객체가 해제 될 때 자동으로 할당 해제해서는 안?)을 Product
MO가 해제 될 때, 지금 관련 MOC가 아닌 것으로 생각된다
내 질문은 : 누군가는 설명 할 경우 추가 참조 그것이 할당 해제되는 것을 막고있는 MOC입니까? MO와 MOC 사이에 보관주기를 만들었습니까?
필요에 따라 작업자 컨텍스트를 삭제하거나 생성하면 안되는 이유는 무엇입니까? 예 : 아직 변경되지 않은 두 개의 MO가 있습니다. 같은 맥락에서 저장이 MO 둘 모두를 유지할 것입니다 - 당신은 단지 그것들 중 하나를 유지하려고했을 것입니다).여러 작업자 컨텍스트를 판매하는 주목할만한 CD 스택 (예 : https://www.bignerdranch.com/blog/introducing-the-big-nerd-ranch-core-data-stack/). –
@SoOverIt 맞습니다. 나는 대답의 마지막 부분을 제거했습니다. 그러나 여전히 사용중인 관리 컨텍스트에 대한 강력한 참조가 있는지 확인해야합니다. – Sulthan
'모든 관리 대상 개체는 관리 컨텍스트에 의해 소유됩니다.' 이것은 전적으로 사실이 아닙니다. 컨텍스트가 삭제 된 관리 대상 개체를 계속 가질 수 있습니다. NSManagedObject Class Reference의 managedObjectContext 문서를 참조하십시오. (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/#//apple_ref/occ/instp/NSManagedObject/ managedObjectContext) - "수신자가 컨텍스트에서 삭제 된 경우 nil 일 수 있습니다." –