我能否创建自定义托管对象类的新实例而不通过 NSEntityDescription?

7

我有一个苹果的例子,内容如下:

Event *event = (Event*)[NSEntityDescription 
    insertNewObjectForEntityForName:@"Event" 
             inManagedObjectContext:self.managedObjectContext];

Event继承自NSManagedObject。有没有什么方法可以避免这种奇怪的调用NSEntityDescription,而是直接使用alloc+init来实例化Event类?我是否需要编写自己的初始化程序来执行上述操作?或者NSManagedObject已经足够智能,可以自动执行这些操作?

4个回答

5

哦,是的,但绝不要覆盖 initWithEntity:insertIntoManagedObjectContext:awakeFromInsert 是进行初始化的适当位置。 - Alex

3
我遇到了完全相同的问题。事实证明,您可以完全创建一个实体,而不首先将其添加到存储中,然后对其进行一些检查,如果一切都好,则将其插入存储中。我在 XML 解析会话期间使用它,只有在实体被正确完全解析后才想要插入它们。
首先,您需要创建实体:
// This line creates the proper description using the managed context and entity name. 
// Note that it uses the managed object context
NSEntityDescription *ent = [NSEntityDescription entityForName:@"Location" inManagedObjectContext:[self managedContext]];

// This line initialized the entity but does not insert it into the managed object context.    
currentEntity = [[Location alloc] initWithEntity:ent insertIntoManagedObjectContext:nil];

当你对处理结果满意后,你可以将实体简单地插入到存储中:

[self managedContext] insertObject:currentEntity

请注意,在这些示例中,currentEntity对象已在头文件中定义如下:
id currentEntity

1

我从Dave Mark和Jeff LeMarche的书《More iPhone 3 Development》中找到了一个明确的答案。

如果你真的很在意使用NSEntityDescrpiton上的方法而不是NSManagedObjectContext来插入新对象到NSManagedObjectContext中,你可以使用分类将实例方法添加到NSManagedObjectContext中。

创建两个名为NSManagedObject-Insert.hNSManagedObject-Insert.m的新文本文件。

NSManagedObject-Insert.h中,放置以下代码:

import <Cocoa/Cocoa.h>
@interface NSManagedObjectContext (insert)
- (NSManagedObject *)insertNewEntityWithName:(NSString *)name;
@end

在NSManagedObject-Insert.m中,放置此代码:

#import "NSManagedObjectContext-insert.h"

@implementation NSManagedObjectContext (insert)
- (NSManagedObject *)insertNewEntityWithName:(NSString *)name
{
return [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:self];
}
@end

您可以在任何想要使用这个新方法的地方导入NSManagedObject-Insert.h。然后将对NSEntityDescription的插入调用替换为以下内容:

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

使用更短、更直观的方式:

[context insertNewEntityWithName:[entity name]];

分类难道不是很棒吗?


1
为了使其正常工作,有很多事情要做。-insertNewObject:…是迄今为止最简单的方法,无论它是否奇怪。文档说:

托管对象与其他对象有三个主要区别——托管对象……存在于由其托管对象上下文定义的环境中……因此,创建新的托管对象并将其正确集成到核心数据基础设施中需要大量工作……不建议覆盖initWithEntity:insertIntoManagedObjectContext:

话虽如此,你仍然可以这样做(请继续阅读我链接的页面),但你的目标似乎是“更容易”或“不那么奇怪”。我认为你觉得奇怪的方法实际上是最简单、最正常的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接