1

接下来是我可能认为的所有背景,以尝试确定错误的来源。当然,我会提供任何其他可能有用的信息。在此先感谢您的帮助。

我是 Core Data 的新手,我有一个名为 GroceryItem 的实体。它有一个名为 hasLocations 的一对多关系,我正在尝试使用以下代码进行查询:

itemObject = (GroceryItem *)[GroceryItem itemNameToObject:itemName];

if (itemObject != nil)
{
    NSLog(@"%@", [NSString stringWithFormat:@"initAndFillItemLocationsTable got an item named %@", itemObject.name]);
}

if (itemLocations != nil)
{
    [itemLocations removeAllObjects];
}

if (itemObject != nil)
{
    NSLog(@"Before mutable set assignment");

    NSMutableSet *mutableLocationsSet = [itemObject mutableSetValueForKeyPath:@"hasLocations"];

我在输出中看到“Before mutable set assignment”消息,然后是

2013-01-23 03:27:14.898 Grocery Manager[6431:11603] initAndFillItemLocationsTable 有一个名为 Cream Cheese 的项目 2013-01-23 03:27:14.899 Grocery Manager[6431:11603] 在可变集分配之前 2013-01-23 03:27:14.901 Grocery Manager[6431:11603] * 由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[valueForUndefinedKey:]:实体 GroceryItems 与键“hasLocations”的键值编码不兼容。*First throw call stack: (0x15eb012 0x1410e7e 0x1673fb1 0x11c304 0xe298db 0xb8374 0xe298db 0xec3180 0xec31de 0x17450 0xaa5c 0x439817 0x439882 0x439b2a 0x450ef5 0x450fdb 0x451286 0x451381 0x451eab 0x4524a3 0x452098 0x7adda3 0x79fad9 0x79fb54 0x407899 0x407b3d 0xe0ee83 0x15aa376 0x15a9e06 0x1591a82 0x1590f44 0x1590e1b 0x24377e3 0x2437668 0x35865c 0x27bd 0x26e5) libc++abi.dylib : 终止调用抛出异常

GroceryItem 类定义的内容是:

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>


@interface GroceryItem : NSManagedObject

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSSet *hasLocations;
@property (nonatomic, retain) NSSet *containedInIngredients;

@end

@interface GroceryItem (CoreDataGeneratedAccessors)

- (void)addHasLocationsObject:(NSManagedObject *)value;
- (void)removeHasLocationsObject:(NSManagedObject *)value;
- (void)addHasLocations:(NSSet *)values;
- (void)removeHasLocations:(NSSet *)values;

- (void)addContainedInIngredientsObject:(NSManagedObject *)value;
- (void)removeContainedInIngredientsObject:(NSManagedObject *)value;
- (void)addContainedInIngredients:(NSSet *)values;
- (void)removeContainedInIngredients:(NSSet *)values;

+(GroceryItem *)itemNameToObject:(NSString *)itemName;

我已经在数据库编辑器中验证了 GroceryItem 类已分配给实体 GroceryItem。

我阅读了 Key-Value Coding Programming Guide 并在 GroceryItem.m 中实现了以下代码:

- (void)addHasLocationsObject:(NSManagedObject *)value
{
    [self.hasLocations setByAddingObject:value];
}

- (void)removeHasLocationsObject:(NSManagedObject *)value
{
    NSMutableSet *mutable = [NSMutableSet setWithSet:self.hasLocations];

    [mutable removeObject:value];

    self.hasLocations = mutable;
}

- (void)addHasLocations:(NSSet *)values
{
    [self.hasLocations setByAddingObjectsFromSet:values];
}

- (void)removeHasLocations:(NSSet *)values
{
    NSMutableSet *mutable = [NSMutableSet setWithSet:self.hasLocations];

    for (id obj in [mutable allObjects])
    {
        if ([values containsObject:obj])
        {
            [mutable removeObject: obj];
        }
    }
    self.hasLocations = mutable;
}

- (NSUInteger)countOfHasLocations
{     
    return [self.hasLocations count];
}

- (NSEnumerator *)enumeratorOfHasLocations
{
    return [self.hasLocations objectEnumerator];
}

- (GroceryLocation *)memberOfHasLocations:(GroceryLocation *)anObject
{
    return [self.hasLocations member:anObject];

}

静态 itemNameToObject 函数如下所示:

+(GroceryItem *)itemNameToObject:(NSString *)itemName
{
    GroceryItem *groceryItem;

    groceryItem = nil;

    if (itemName != nil)
    {
        GroceryManagerAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

        NSManagedObjectContext *context = [appDelegate managedObjectContext];

        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        [request setEntity:[NSEntityDescription entityForName:@"GroceryItems" inManagedObjectContext:context]];

        [request setPredicate:[NSPredicate predicateWithFormat:@"name == %@", itemName]];

        NSError *error;
        NSArray *groceryItemObjects = [context executeFetchRequest:request error:&error];

        NSInteger countOfGroceryItems = [groceryItemObjects count];

        if (countOfGroceryItems == 1)
        {
            groceryItem = (GroceryItem *)[groceryItemObjects objectAtIndex:0];
        }
    }

    return groceryItem;
}
4

1 回答 1

1

(来自评论:)崩溃是由于实体被声明为“GroceryItems”,但“hasLocations”是“GroceryItem”类的属性引起的。获取请求返回一个“GroceryItems”对象数组,这些对象不响应“hasLocations”方法。

此外,通常不需要实现 Core Data 访问器方法,它们是在运行时动态创建的。

于 2013-01-24T07:41:38.387 回答