我想以简单的方式创建一个NSManagedObject子类的实例:Library *library = [[Library alloc] init]
所以我像这样覆盖init
方法。
- (instancetype)init
{
NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSMainQueueConcurrencyType];
managedObjectContext.parentContext = [RKManagedObjectStore
defaultStore].mainQueueManagedObjectContext;
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Library"
inManagedObjectContext: managedObjectContext];
self = [super initWithEntity:entityDescription
insertIntoManagedObjectContext:managedObjectContext];
return self;
}
在视图中,我使用Library *library = [[Library alloc] init]
创建新实例,这非常有用。现在我需要将Book
对象添加到与它有关系的Library
。因此,新的Book
实例应与其父{ - 1}}位于同一managedObjectContext
。要正确实例化Library
,我需要获取Book
的managedObjectContent:Library
返回[library managedObjectContent]
。几个小时后,我有一个解决方法:
nil
在GTObjectManager中,我只使用与旧的init方法相同的代码:
- (instancetype)init
{
NSManagedObjectContext *managedObjectContext = [GTObjectManager newManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"City"
inManagedObjectContext: managedObjectContext];
self = [super initWithEntity:entityDescription
insertIntoManagedObjectContext:managedObjectContext];
return self;
}
现在,在实例化+ (NSManagedObjectContext *)newManagedObjectContext
{
NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSMainQueueConcurrencyType];
managedObjectContext.parentContext = [RKManagedObjectStore
defaultStore].mainQueueManagedObjectContext;
return managedObjectContext;
}
之后调用Library *library = [[Library alloc] init]
不会返回[library managedObjectContext]
。所以澄清一下:如果在nil
方法中创建managedObjectContext
,我在实例化后无法获取它。如果在init
方法之外创建managedObjectContent
,我可以在实例化后获取它。
我无法解释这种行为。这是init
方法的行为吗?我正在使用ARC,它是某种ARC行为吗?
答案 0 :(得分:1)
在您的第一个 init
函数中,您创建一个本地managedObjectContext
对象并使用它来创建托管对象。 托管对象不保留其上下文,因此managedObjectContext
是对象的唯一强引用。 ARC添加代码以在函数末尾释放此引用,并且由于它是唯一的引用,因此将释放托管对象上下文。
如果您将以下代码添加到init
函数(self = [super initWithEntity:...]
之后),则可以观察到此行为:
NSLog(@"%@", [self managedObjectContext]);
// Output: <NSManagedObjectContext: 0x100134a00>
managedObjectContext = nil;
NSLog(@"%@", [self managedObjectContext]);
// Output: (null)
如您所见,如果上下文已被释放,则向托管对象询问其上下文将返回nil
。
在您的第二个 init
函数中,应该完全相同,我在测试程序中观察到完全相同的行为。但这取决于如何调用返回新上下文的实用程序方法。
在您的代码示例中,它被称为newManagedObjectContext
。以new...
开头的方法返回保留的对象,并在init函数结束时释放。因此,您的两个init
函数之间应该没有区别。
然而,如果调用实用方法,例如getManagedObjectContext
,然后返回(粗略地说)一个自动释放的对象。此对象可能存在的时间更长,直到当前的自动释放池被销毁。
也许这就解释了为什么如果在实用程序方法中创建上下文,您的代码似乎有效。
结论: 如果以后需要这些对象,创建本地临时上下文来创建对象是没有意义的。托管对象存在于上下文中,如果上下文被破坏,则无法再使用这些对象。
您必须先决定要使用哪个上下文,然后在该上下文中创建对象及其关系。