2

コア データを使用して、イベントなどのエンティティを保持したいと考えています。

したがって、私はクラスを使用しDSManagedObjectEvent

このクラスDSManagedObjectは拡張NSManagedObjectされ、すべてのエンティティが使用できる一般的なメソッドがあります。クラスEventが拡張されDSManagedObjectます。

次のコードはDSManagedObject.h.mです。関連するコードは-method.mだけです。getContext

@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 をオーバーライドして、初期化をカスタマイズできる 3 つの異なる方法があります。init をオーバーライドしないでください。initWithEntity:insertIntoManagedObjectContext: をオーバーライドしないことをお勧めします。このメソッドで行われた状態の変更は、元に戻すおよびやり直しと適切に統合されない可能性があるためです。他の 2 つのメソッド、awakeFromInsert と awakeFromFetch を使用すると、2 つの異なる状況を区別できます。

したがって、解決策は initWithEntity:insertIntoManagedObjectContext: をオーバーライドするか、 or を利用することawakeFromInsertですawakeFromFecthinitWithEntity:insertIntoManagedObjectContext:またはを呼び出した後に が呼び出されるため、必要に応じて前者を無視してください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 に答える