gpt4 book ai didi

ios - RestKit - 'Cannot add object with entity ' entityName' 为 'entityName'' 的实体缓存

转载 作者:行者123 更新时间:2023-11-29 01:29:45 25 4
gpt4 key购买 nike

我在 uitabbarcontroller 中有带三个 View Controller 的 iPad 应用程序。在每个 View Controller 中,我调用不同的 Web 服务并使用 RestKit 将它们映射到核心数据实体,然后使用 nsfetchedresultscontroller 在 uitableview 中显示数据。有关我的实现的更多信息是 here .

第一次加载数据时,数据已正确加载并映射到每个 View Controller 上,但在其中一个 View Controller 中,当我在 View Controller 3 中加载数据后尝试重新加载 View Controller 2 中的数据时,应用程序因以下错误而崩溃:

2015-11-07 00:17:45.205 PharmacyStockTake[193:3854] Trestkit.network:RKResponseMapperOperation.m:504 将 HTTP 响应映射到 nil 目标对象...2015-11-07 00:17:45.206 PharmacyStockTake [193:3854]我restkit.core_data:RKInMemoryManagedObjectCache.m:94通过属性“stockTakeLocId”缓存实体“RackStockTakeStatus”的实例2015-11-07 00:17:45.213 PharmacyStockTake[193:3854] * -[RKEntityByAttributeCache addObjects:completion:] 中的断言失败,/Users/saif/Documents/iDev/ComPrjs/PharmacyStockTake/Pods/RestKit/Code/CoreData/RKEntityByAttributeCache.m:3332015-11-07 00:17:45.214 PharmacyStockTake[193:3854] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法添加具有实体“RackStockTakeStatus”的对象来缓存“RackStockTakeStatus”实体'*** 首先抛出调用栈:(0x2201585b 0x33a5adff 0x22015731 0x22da6ddb 0x14b67b 0x21d9034b 0x21d9022d 0x14b175 0x15a9e1 0x21d9034b 0x21d9022d 0x15a71d 0 x161327 0x17bfb9 0x17a769 0x220091e9 0x21f8bbdb 0x17a65b 0x17c21b 0x17c9cd 0x17d271 0x22d283cf 0x1c3925 0x21d9034b 0x422d03 0 x42c4fb 0x21d90247 0x1c26bb 0x1c072d 0x22d283cf 0x22dd682d 0x42d61b 0x425f53 0x42eb0f 0x42e961 0x34314e0d 0x343149fc)libc++abi.dylib:以 NSException 类型的未捕获异常终止

这是我的代码:

在AppDelegate中初始化RestKit:

RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];

//[RKObjectManager setSharedManager:objectManager];
[RKObjectManager setSharedManager:objectManager];


// Initialize managed object model from bundle
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

// Initialize managed object store
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;

// Complete Core Data stack initialization
[managedObjectStore createPersistentStoreCoordinator];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"StockTakeDB.sqlite"];
NSString *seedPath = [[NSBundle mainBundle] pathForResource:@"StoreItemsDB" ofType:@"sqlite"];
NSError *error;
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:seedPath withConfiguration:nil options:nil error:&error];
NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);

// Create the managed object contexts
[managedObjectStore createManagedObjectContexts];

// Configure a managed object cache to ensure we do not create duplicate objects
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];

View-Controller-2 中的 RestKit 初始化和配置代码:

-(void)initTakeStockRestKit
{
takeStockLocationWithStatusRequestPath = @"/stocktake/stocktake/1/usr/1/locwithstatus";
RKObjectManager *objectManager = [RKObjectManager sharedManager];

[[NSURLCache sharedURLCache] removeAllCachedResponses];

// Initialize managed object model from bundle
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

// Initialize managed object store
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;

// Complete Core Data stack initialization
[managedObjectStore createPersistentStoreCoordinator];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"StockTakeDB.sqlite"];
NSString *seedPath = [[NSBundle mainBundle] pathForResource:@"StoreItemsDB" ofType:@"sqlite"];
NSError *error;
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:seedPath withConfiguration:nil options:nil error:&error];
NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);

// Create the managed object contexts
[managedObjectStore createManagedObjectContexts];

// Configure a managed object cache to ensure we do not create duplicate objects
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];

[objectManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {
RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:takeStockLocationWithStatusRequestPath];

NSDictionary *argsDict = nil;
BOOL match = [pathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:&argsDict];

if (match) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"RackStockTakeStatus"];
return fetchRequest;
}
return nil;
}];

RKEntityMapping *rackStockTakeStatusListMapping = [RKEntityMapping mappingForEntityForName:@"RackStockTakeStatus" inManagedObjectStore:managedObjectStore];
rackStockTakeStatusListMapping.identificationAttributes = @[@"stockTakeLocId"];

[rackStockTakeStatusListMapping addAttributeMappingsFromDictionary:
@{
@"stockTakeLocId" : @"stockTakeLocId",
@"stockTakeUuid" : @"stockTakeUuid",
@"locId" : @"locId",
@"locName" : @"locName",
@"status" : @"status",
@"stockTakeByUser" : @"stockTakeByUser",
@"stockTakeByUserId" : @"stockTakeByUserId",
@"beginTime" : @"beginTime",
@"percentCompleted" : @"percentCompleted"
}
];

RKResponseDescriptor *rackStockTakeStatusListResponseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:rackStockTakeStatusListMapping
method:RKRequestMethodGET
pathPattern:@"/stocktake/stocktake/:id/usr/:id/locwithstatus"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
];

[objectManager addResponseDescriptor:rackStockTakeStatusListResponseDescriptor];
}

View-Controller-2 上的数据加载:

NSString *requestPath = [NSString stringWithFormat:@"/stocktake/stocktake/%@/usr/1/locwithstatus",[defaults objectForKey:@"loggedInUserSelectedStoreId"]];

[[RKObjectManager sharedManager]
getObjectsAtPath:requestPath
parameters:nil
success: ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSManagedObjectContext *context = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"RackStockTakeStatus" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error;
[context executeFetchRequest:request error:&error];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
}
[self.tableView reloadData];
NSLog(@"requestDataItemsForStore - Mapping Success");
}
failure: ^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(@"Load failed with error: %@", error);
NSLog(@"requestDataItemsForStore - Loading Failed");
}
];

View-Controller-3 中的 RestKit 初始化和配置代码:

RKObjectManager *objectManager = [RKObjectManager sharedManager];

// Initialize managed object model from bundle
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

// Initialize managed object store
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;

// Complete Core Data stack initialization
[managedObjectStore createPersistentStoreCoordinator];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"StockTakeDB.sqlite"];
NSString *seedPath = [[NSBundle mainBundle] pathForResource:@"StoreItemsDB" ofType:@"sqlite"];
NSError *error;
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:seedPath withConfiguration:nil options:nil error:&error];
NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);

// Create the managed object contexts
[managedObjectStore createManagedObjectContexts];

// Configure a managed object cache to ensure we do not create duplicate objects
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];

[objectManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {
RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:itemsByLocationRequestPath];

NSDictionary *argsDict = nil;
BOOL match = [pathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:&argsDict];

if (match) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"ItemsByLocation"];
return fetchRequest;
}

return nil;
}];

RKEntityMapping *itemsByLocationListMapping = [RKEntityMapping mappingForEntityForName:@"ItemsByLocation" inManagedObjectStore:managedObjectStore];
itemsByLocationListMapping.identificationAttributes = @[@"itemId"];

[itemsByLocationListMapping addAttributeMappingsFromDictionary:
@{
@"itemId" : @"itemId",
@"itemName" : @"itemName",
@"itemCode" : @"itemCode",
@"uomCode" : @"uomCode",
@"locId" : @"locId",
@"locName" : @"locName",
@"subLocId" : @"subLocId",
@"subLocName" : @"subLocName",
@"storeItemId" : @"storeItemId",
@"stockTakeQtyId" : @"stockTakeQtyId",
@"countedTime" : @"countedTime",
@"countQty" : @"countQty",
@"removed" : @"removed",
@"remarks" : @"remarks"
}
];

RKResponseDescriptor *itemsByLocationListResponseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:itemsByLocationListMapping
method:RKRequestMethodGET
pathPattern:@"/stocktake/stocktake/:id/loc/:id/usr/:id/items"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
];

[objectManager addResponseDescriptor:itemsByLocationListResponseDescriptor];

View Controller-3 上的数据加载:

    [[RKObjectManager sharedManager]
getObjectsAtPath:itemsByLocationRequestPath
parameters:nil
success: ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSManagedObjectContext *context = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"ItemsByLocation"];

NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"subLocName" ascending:YES];
fetchRequest.sortDescriptors = @[descriptor];

NSError *error = nil;
[context executeFetchRequest:fetchRequest error:&error];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {

}
[self.tableView reloadData];
NSLog(@"requestDataItemsForStore - Mapping Success");
}
failure: ^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(@"Load failed with error: %@", error);
NSLog(@"requestDataItemsForStore - Loading Failed");
}
];

你能帮忙解决这个问题吗?

最佳答案

这是一个线程和/或多上下文问题。您的实体缓存是在一个上下文中设置的,但随后您从不同的上下文中使用它(这就是实体具有相同名称但不同的原因)。

这可能是因为您正在设置多个不同的核心数据堆栈(从代码示例中看起来是这样)。在这种情况下,您应该分解出所有核心数据堆栈并将创建代码映射到一个新类 - 数据管理器中。将数据管理器传递给每个 View Controller ,以便它们可以使用它来下载所需的内容。

如果是线程问题,则打开核心数据线程异常可以帮助您找到原因。

请注意,在每个 View Controller 中使用 FRC 很好,但是您应该只有一个主线程上下文来设置它们。

关于ios - RestKit - 'Cannot add object with entity ' entityName' 为 'entityName'' 的实体缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33571240/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com