【发布时间】:2010-02-11 12:44:32
【问题描述】:
我有两个实体,我也建模为类和核心数据模型实体/这些类如下所示:
类:StateManager
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "StateManager.h"
#import "Constants.h"
@implementation StateManager
@synthesize deviceID, physicalID, applicationName, applicationVersion;
@synthesize userName, userPassword, server, port, client, language, protocol;
-(bool)checkCompleteness{
if (physicalID == nil) {
return false;
}
if (applicationName == nil) {
return false;
}
if (applicationVersion == nil) {
return false;
}
if (userName == nil) {
return false;
}
if (userPassword == nil) {
return false;
}
if (port == nil) {
return false;
}
if (server == nil) {
return false;
}
return true;
}
-(void)preserveState:(NSManagedObjectContext *)managedObjectContext{
// Step 1: Create Object
StateManager *inMemoryState = (StateManager *)[NSEntityDescription
insertNewObjectForEntityForName:ENTITY_STATE
inManagedObjectContext:managedObjectContext];
// Step 2: Set Properties
[inMemoryState setDeviceID:self.deviceID];
[inMemoryState setPhysicalID:self.physicalID];
[inMemoryState setApplicationName:self.applicationName];
[inMemoryState setApplicationVersion:self.applicationVersion];
//[inMemoryState setAutoRegister:[self getAutoRegister]];
[inMemoryState setUserName:self.userName];
[inMemoryState setUserPassword:self.userPassword];
[inMemoryState setServer:self.server];
[inMemoryState setPort:self.port];
[inMemoryState setClient:self.client];
[inMemoryState setLanguage:self.language];
[inMemoryState setProtocol:self.protocol];
// Step 3: Save Object
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved Core Data Save error %@, %@", error, [error userInfo]);
exit(-1);
}
}
-(StateManager *)loadState:(NSManagedObjectContext *)managedObjectContext{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityState = [NSEntityDescription entityForName:ENTITY_STATE
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityState];
NSError *error;
NSArray *items = [managedObjectContext
executeFetchRequest:fetchRequest error:&error];
if ([items count] > 0) {
StateManager *inDatabaseState = (StateManager *)[items objectAtIndex:0];
deviceID = [inDatabaseState valueForKey:@"deviceID"];
physicalID = [inDatabaseState valueForKey:@"physicalID"];
applicationName = [inDatabaseState valueForKey:@"applicationName"];
applicationVersion = [inDatabaseState valueForKey:@"applicationVersion"];
//autoRegister = [inDatabaseState valueForKey:@"autoRegister"];
userName = [inDatabaseState valueForKey:@"userName"];
userPassword = [inDatabaseState valueForKey:@"userPassword"];
server = [inDatabaseState valueForKey:@"server"];
port = [inDatabaseState valueForKey:@"port"];
client = [inDatabaseState valueForKey:@"client"];
language = [inDatabaseState valueForKey:@"language"];
protocol = [inDatabaseState valueForKey:@"protocol"];
[inDatabaseState release];
}
[fetchRequest release];
[entityState release];
[items release];
/*
deviceID = @"1234";
physicalID = @"12312";
applicationName = @"erwerw";
applicationVersion = @"applicationVersion";
//autoRegister = [inDatabaseState valueForKey:@"autoRegister"];
userName = @"userName";
userPassword = @"userPassword";
server = @"server";
port = @"port";
client = @"client";
language = @"language";
protocol = @"protocol";*/
return self;
}
-(void)dealloc{
[deviceID release];
[physicalID release];
[applicationName release];
[applicationVersion release];
[userName release];
[userPassword release] ;
[server release];
[port release];
[client release];
[language release];
[protocol release];
[super dealloc];
}
@end
类:InboundQueueState
#import "InQueueState.h"
@implementation InQueueState
@dynamic top;
@dynamic read;
@dynamic last;
@end
现在我正在尝试将这些对象数据从数据库加载到我的应用程序中的两个不同位置,如下所示:
如果您查看 StateManager 类,您会看到一个方法 loadState,它尝试使用托管对象上下文读取实体“StateManager”。这个上下文是从主类传递给这个类的。
-
下面“InboundQueue”类中显示的另一个方法“readQueue”尝试遵循使用全局托管对象上下文加载实体“InboundState”的相同范例,但失败并出现以下错误:
错误:[NSFetchRequest objectID]:无法识别的选择器发送到 实例 0x3a1a300 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'*** -[NSFetchRequest objectID]: 无法识别的选择器发送到实例 0x3a1a300'
类:入站队列
#import "InboundQueue.h"
#import <CoreData/CoreData.h>
#import "Constants.h"
#import "InQueueItem.h"
@implementation InboundQueue
-(int)last{
return [queueState last];
}
-(int)top{
return [queueState top];
}
-(int)read{
return [queueState read];
}
-(InboundQueue *)initInboundQueue:(NSManagedObjectContext *)managedObjectContext{
//load the inbound queue counters and initialize the inbound queue object with the values
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityState = [NSEntityDescription entityForName:INQUEUE_STATE
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityState];
NSError *error;
NSArray *msgs = [managedObjectContext
executeFetchRequest:fetchRequest error:&error];
if ([msgs count] > 0) {
queueState = [msgs objectAtIndex:0]; //contains the values of the counters related to inbound queue at any point in time
}
[fetchRequest, entityState, msgs release];
return self;
}
-(NSMutableArray *)readQueue:(NSManagedObjectContext*) managedObjectContext{
//load the inbound queue counters and initialize the inbound queue object with the values
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityState = [NSEntityDescription entityForName:INQUEUE
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityState];
NSError *error;
NSArray *queueContent = [managedObjectContext
executeFetchRequest:fetchRequest error:&error];
[queueData setArray:queueContent];
[fetchRequest, entityState, error release];
return queueData;
}
-(void)confirm:(int)msgID managedObjectContext:(NSManagedObjectContext*) managedObjectContext{
if (msgID < [queueState top]) {
return;
}
if (msgID > [queueState last]) {
return;
}
//remove items from queue which are lower than the confrmed message ID
for (InQueueItem *item in queueData) {
int currentMsgId = [item MSG_ID];
if ( currentMsgId <= msgID) {
//delete the item from queue and adjust counters
[queueData removeObject:item];
}
}
[queueState setTop:(msgID + 1)];
if ([queueState read] < [queueState top]) {
[queueState setRead:[queueState top]]; //realign the top counter
}
//persist the changes from context to database
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved Core Data Save error %@, %@", error, [error userInfo]);
exit(-1);
}
}
-(void)add:(InQueueItem *)item managedObjectContext:(NSManagedObjectContext*) managedObjectContext{
//validate the message id
if (([queueState last] > ([item MSG_ID] - 1))) {
//ignore this message since we have already received a message with this message id
}else if (([queueState last] < ([item MSG_ID] - 1))) {
//raise an invalid message ID exception => data loss
}else {
if ([queueState last] == 0) {
//need to initialize counters as this is the first entry
[queueState setTop:[item MSG_ID]];
[queueState setLast:[item MSG_ID]];
}else {
//increment last
[queueState setLast:([queueState last] + 1)];
}
//now insert the item into queue
[queueData addObject:item];
}
//persist the changes from context to database
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved Core Data Save error %@, %@", error, [error userInfo]);
exit(-1);
}
}
-(void)dealloc{
[queueData release];
[queueState release];
[super dealloc];
}
@end
我的理解是同一个托管对象上下文可以加载数据模型的所有对象并允许操作,但我不确定为什么在我的情况下它只适用于一个对象。
【问题讨论】:
-
你能告诉我们你获取这两个实体的代码吗?
-
不,您不需要单独的托管对象上下文;问题一定是别的。请发布更多详细信息。