2

我想使用核心数据来持久化一些实体,比如事件。

因此我使用类DSManagedObjectEvent

该类DSManagedObject扩展NSManagedObject并具有所有实体都可以使用的通用方法。类Event扩展DSManagedObject

下面的代码是DSManagedObject.hand .m。中的相关代码.m就是getContext-method。

@interface DSManagedObject : NSManagedObject

+ (NSManagedObjectContext *)getContext;
- (NSArray*)getEntitiesForName:(NSString*)_entityName context:(NSManagedObjectContext*)_context;
- (Event*)getEntityForName:(NSString*)_entityName forEventId:(NSInteger)_eventId context:(NSManagedObjectContext*)_context;
- (bool)deleteEntityForName:(NSString*)_entityName forEventId:(NSInteger)_eventId context:(NSManagedObjectContext*)_context;

@end


@implementation DSManagedObject

+ (NSManagedObjectContext *)getContext {

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES],
                             NSInferMappingModelAutomaticallyOption, nil];


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    NSURL *storeUrl = [NSURL fileURLWithPath:[basePath stringByAppendingFormat:@"DesertStorm.sqlite"]];
    NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
    NSError *error = nil;

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        NSLog(@"error loading persistent store..");
        [[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:nil];
        if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }



    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
    [context setPersistentStoreCoordinator:persistentStoreCoordinator];

    return context;


}

现在在Event我想调用的类中,initWithEntity但随后[Event managedObjectModel] unrecognized selector sent to instance发生错误。什么原因 ?:(

@interface Event : DSManagedObject

@property (assign)              NSInteger   eventId;

@end


@implementation Event

@dynamic eventId;

- (id)init {

    NSEntityDescription *entity = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:[DSManagedObject getContext]];
    self = [self initWithEntity:entity insertIntoManagedObjectContext:[DSManagedObject getContext]];  // error occurs
    self = [super init];
    if (self) {

    }
    return self;
}

...

@end

我是使用核心数据的新手,所以表现出理解;)感谢您的帮助

PS:如果你想知道我为什么要覆盖init-method...复杂的原因^^

4

2 回答 2

5

来自核心数据文档:

在典型的 Cocoa 类中,您通常会覆盖指定的初始化程序(通常是 init 方法)。在 NSManagedObject 的子类中,您可以通过三种不同的方式自定义初始化——通过覆盖 initWithEntity:insertIntoManagedObjectContext:、awakeFromInsert 或 awakeFromFetch。您不应该覆盖 init。不鼓励您覆盖 initWithEntity:insertIntoManagedObjectContext: 因为在此方法中所做的状态更改可能无法与撤消和重做正确集成。另外两种方法 awakeFromInsert 和 awakeFromFetch 允许您区分两种不同的情况:

因此,灵魂建议是覆盖 initWithEntity:insertIntoManagedObjectContext: 或利用awakeFromInsertor awakeFromFecth。如果需要,可以在调用initWithEntity:insertIntoManagedObjectContext:or之后调用 ovveride 前者,因为它会被调用insertNewObjectForEntityForName:inManagedObjectContext:

是否有您想要实现的特定目标?

编辑

尝试覆盖initWithEntity:insertIntoManagedObjectContext:而不是init

- (id)initWithEntity:(NSEntityDescription*)entity insertIntoManagedObjectContext:(NSManagedObjectContext*)context    
{    
    self = [super initWithEntity:entity insertIntoManagedObjectContext:context];
    if (self != nil) {

        // Perform additional initialization.

    }

    return self;    
}

该方法是 NSManagedObject 的指定初始化器。您不能简单地通过发送 init 来初始化托管对象。请参阅NSManagedObject课程以获取更多信息。

于 2012-07-09T10:58:55.800 回答
0

我在 - 方法中解决了这个问题init。我仍然重写该方法(我知道我不应该,但是……无论如何)

这是代码

- (id)init {
    return [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:[DSManagedObject getContext]];
}

这将返回一个 NSManagedObject 并且不会发生错误:)

于 2012-07-09T12:52:58.453 回答