我在获取属性方面面临一个大问题。
我在模型中有这个实体:
EntityDetail
Attributes:
NSString: idd_info
[...]
Fetched Property:
Name: info Destination: EntityInfo Predicate: idd==$FETCH_SOURCE.idd_info
EntityInfo
Attributes:
NSString: idd
NSString: title
[...]
这样我可以在需要的时候获取相关的EntityInfo:
[[detail.info objectAtIndex:0] title]
由于解析过程中的性能原因,我更喜欢这种方法而不是配置常规关系。
如果我使用 Apple 生成的 CoreData 样板来设置堆栈,一切正常,我可以成功使用 fetched 属性。但是,如果我使用 RKManagedObjectStore 类提供的 RestKit 实现,则 fetched 属性不起作用。这是错误:
由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[<_NSObjectID_48_15 0x1a2f9ac0> valueForUndefinedKey:]:此类与键 idd_info 的键值编码不兼容。”
似乎 $FETCH_SOURCE 解析为 NSObjectID 而不是 NSObject 本身。而且,显然,idd_info 属性没有在该类上定义。
谷歌搜索我发现了将 fetchRequest 上的 resultType 设置为 NSManagedObjectResultType 的可能性。这是 Apple 文档中所述的默认行为。那么为什么 RestKit 0.20.3 改用 NSManagedObjectIDResultType 呢?使用 RestKit 0.10 一切正常...
这是一个已知的错误吗?如何将获取的属性强制为 NSManagedObjectResultType ?
这是我使用 RKManagedObjectStore 设置持久存储和创建托管对象上下文的方式。我在应用程序委托中,_managedObjectModel _managedObjectStore _managedObjectContext 是整个应用程序中使用的单例变量)。
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"MyApp" ofType:@"momd"]];
_managedObjectModel= [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
_managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:_managedObjectModel];
[_managedObjectStore createPersistentStoreCoordinator];
NSString *storePath = [[self docDir] stringByAppendingPathComponent::@"MyApp.sqlite"];
NSDictionary *options = @{ NSSQLitePragmasOption : @{@"journal_mode" : @"DELETE"} };
NSPersistentStore __unused *persistentStore = [_managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:nil withConfiguration:nil options:options error:&error];
NSAssert(persistentStore, @"Failed to add persistent store: %@", error);
[_managedObjectStore createManagedObjectContexts];
[RKManagedObjectStore setDefaultStore:_managedObjectStore];
[_managedObjectStore.mainQueueManagedObjectContext setUndoManager:nil];
_managedObjectContext = _managedObjectStore.mainQueueManagedObjectContext;
谢谢你。
更新 1:
如果我使用:
_managedObjectContext = _managedObjectStore.persistentStoreManagedObjectContext;
代替:
_managedObjectContext = _managedObjectStore.mainQueueManagedObjectContext;
在启动时的应用程序委托中,该问题不会发生并且获取的属性工作正常,但它仍然在映射期间发生。
这就是我设置映射的方式。
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:baseURL];
[RKMIMETypeSerialization registerClass:[RKXMLReaderSerialization class] forMIMEType:@"application/xml"];
[[RKObjectManager sharedManager] setAcceptHeaderWithMIMEType:RKMIMETypeTextXML];
[RKObjectManager setSharedManager:objectManager];
RKManagedObjectStore* objectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:appDeleg.managedObjectModel];
[objectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:nil withConfiguration:nil options:@{ NSInferMappingModelAutomaticallyOption: @YES,NSMigratePersistentStoresAutomaticallyOption: @YES, NSSQLitePragmasOption: @{@"journal_mode" : @"DELETE"} } error:nil];
[objectStore createManagedObjectContexts];
objectManager.managedObjectStore=objectStore;
[objectManager.HTTPClient setAuthorizationHeaderWithUsername:usernameString password:passwordString]
[... here RKEntityMappings and ResponseDescriptors added to the objectManager ...]
[[RKObjectManager sharedManager] getObjectsAtPath:remoteBaseAddedPath parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[delegate parserDidSuccessParsingData:self];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
[delegate parserDidFailParsingData:self withError:error];
}];
更新 2:
这是映射期间的堆栈跟踪。请注意,我在使用 getter 中获取的属性的对象上有一个瞬态属性,RestKit 调用此 getter 并发生崩溃:
2014-03-20 11:10:53.545 MyApp[15378:f03] D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2014-03-20 11:10:53.549 MyApp[15378:60b] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSTemporaryObjectID_default 0xcb9a870> valueForUndefinedKey:]: this class is not key value coding-compliant for the key idd_info.'
*** First throw call stack:
(
0 CoreFoundation 0x02b021e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x028818e5 objc_exception_throw + 44
2 CoreFoundation 0x02b91fe1 -[NSException raise] + 17
3 Foundation 0x00f6dc7a -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 282
4 Foundation 0x00edadfd _NSGetUsingKeyValueGetter + 81
5 Foundation 0x00eda437 -[NSObject(NSKeyValueCoding) valueForKey:] + 260
6 Foundation 0x00ef9f0a -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 409
7 Foundation 0x00eab465 -[NSFunctionExpression expressionValueWithObject:context:] + 1260
8 CoreData 0x00728bbc -[NSSQLSimpleWhereIntermediate initWithPredicate:inScope:] + 620
9 CoreData 0x007283eb -[NSSQLGenerator generateWhereIntermediatesInContext:] + 187
10 CoreData 0x00727dc1 -[NSSQLGenerator generateIntermediatesForFetchInContext:countOnly:] + 673
11 CoreData 0x007242f3 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 483
12 CoreData 0x00723fb8 -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 472
13 CoreData 0x00723dd0 -[NSSQLAdapter newSelectStatementWithFetchRequest:] + 48
14 CoreData 0x00723b91 -[NSSQLCore newRowsForFetchPlan:] + 129
15 CoreData 0x0072331d -[NSSQLCore objectsForFetchRequest:inContext:] + 701
16 CoreData 0x00722dcf -[NSSQLCore executeRequest:withContext:error:] + 383
17 CoreData 0x007227f2 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 4466
18 CoreData 0x0071ff56 -[NSManagedObjectContext executeFetchRequest:error:] + 566
19 CoreData 0x00774d86 -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:] + 502
20 CoreData 0x007f2a14 __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke + 676
21 CoreData 0x00774b81 internalBlockToNSManagedObjectContextPerform + 17
22 libdispatch.dylib 0x032394d0 _dispatch_client_callout + 14
23 libdispatch.dylib 0x03226740 _dispatch_barrier_sync_f_invoke + 58
24 libdispatch.dylib 0x032263ea dispatch_barrier_sync_f + 89
25 CoreData 0x00774b02 _perform + 114
26 CoreData 0x007749ae -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:] + 238
27 CoreData 0x0071ff56 -[NSManagedObjectContext executeFetchRequest:error:] + 566
28 CoreData 0x00774d86 -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:] + 502
29 CoreData 0x007f2a14 __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke + 676
30 CoreData 0x00774b81 internalBlockToNSManagedObjectContextPerform + 17
31 libdispatch.dylib 0x032394d0 _dispatch_client_callout + 14
32 libdispatch.dylib 0x03228439 _dispatch_barrier_sync_f_slow_invoke + 80
33 libdispatch.dylib 0x032394d0 _dispatch_client_callout + 14
34 libdispatch.dylib 0x03227726 _dispatch_main_queue_callback_4CF + 340
35 CoreFoundation 0x02b6743e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
36 CoreFoundation 0x02aa85cb __CFRunLoopRun + 1963
37 CoreFoundation 0x02aa79d3 CFRunLoopRunSpecific + 467
38 CoreFoundation 0x02aa77eb CFRunLoopRunInMode + 123
39 GraphicsServices 0x0392c5ee GSEventRunModal + 192
40 GraphicsServices 0x0392c42b GSEventRun + 104
41 UIKit 0x012bff9b UIApplicationMain + 1225
42 MyApp 0x001a186c main + 76
43 libdyld.dylib 0x0346e701 start + 1
44 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException