0

RPC API 経由でサーバーにアクセスする NSIncrementalStore を実装しようとしています。すべてのデータをローカルにキャッシュする必要があるため、NSIncrementalStore を作成して、キャッシュとして使用される別のコア データ スタックを使用することから始めました。

そのため、最初にメタデータをセットアップし、キャッシュが使用するコア データ スタックをセットアップします。キャッシュ SQL ファイルは、ストアの初期化時に渡される URL です。

    - (BOOL)loadMetadata:(NSError *__autoreleasing *)error {

NSMutableDictionary *mutableMetadata = [NSMutableDictionary dictionary];
[mutableMetadata setValue:[[NSProcessInfo processInfo] globallyUniqueString] forKey:NSStoreUUIDKey];
[mutableMetadata setValue:RTkCachedAPIStoreType forKey:NSStoreTypeKey];
//[mutableMetadata setValue:NSStringFromClass([self class]) forKey:NSStoreTypeKey];
[self setMetadata:mutableMetadata];

// Set up the Cache Stack
NSManagedObjectModel *model = [self.persistentStoreCoordinator.managedObjectModel copy];
self.cacheModel = model;

self.cachePersistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.cacheModel];

self.cacheContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

NSURL *storeURL;
if ([self.URL isFileURL]) {
    storeURL = self.URL;
}

NSError *storeAddError = nil;
if (![self.cachePersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                        configuration:nil
                                                                  URL:storeURL
                                                              options:nil
                                                                error:&storeAddError]) {
    NSLog(@"Fatal error while creating persistent store: %@", storeAddError);
    abort();
}

[self.cacheContext setPersistentStoreCoordinator:self.cachePersistentStoreCoordinator];

return YES;
}

エンティティに対する単純なリクエストの実行リクエストは、次のコードのようになります。基本的には、リクエストを受け取って FetchRequest としてラップし、キャッシュ コア データ スタックでリクエストを実行するだけです。次に、返された objectID を呼び出しコンテキストで使用してオブジェクトを作成します。

- (id)executeRequest:(NSPersistentStoreRequest *)request withContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error {

if ([request requestType] == NSFetchRequestType) {
    NSFetchRequest *fetchRequest = (NSFetchRequest *)request;
    NSEntityDescription *entity = [fetchRequest entity];

    NSFetchRequest *cacheFetchRequest = [[NSFetchRequest alloc] init];
    cacheFetchRequest.entity = entity;
    __block NSArray *fetchedObjectFromCache;
    [self.cacheContext performBlockAndWait:^(){
        fetchedObjectFromCache = [self.cacheContext executeFetchRequest:cacheFetchRequest error:error];
    }];
    NSMutableArray *fetchedObjects = [NSMutableArray arrayWithCapacity:[fetchedObjectFromCache count]];
    for (NSManagedObject *anObject in fetchedObjectFromCache) {
        NSManagedObjectID *objectID = anObject.objectID;
        NSManagedObject *managedObject = [context objectWithID:objectID];
        [fetchedObjects addObject:managedObject];
    }
    return fetchedObjects;
}
}

これを試してみると、エラーで例外がスローされます

<unknown>:0: error: -[] : Object's persistent store is not reachable from this NSManagedObjectContext's coordinator

行で、NSManagedObject *managedObject = [context objectWithID:objectID];これがなぜなのかわかりません-これは、アップルがドキュメントでこれを行うことを示唆している正確な方法です!

このエラーは、スレッド間でのコンテキストへのアクセスに関連しているようですが、私はそうしていません。ここで何が間違っているかについての提案はありますか?

4

1 に答える 1

3

間違った objectID を使用しています。

キャッシュの objectID は、永続ストアの objectID と一致しません。これは、インクリメンタル ストアが同じ識別子を持っていないためです。

于 2014-01-14T21:53:09.580 に答える