1

以下は、エラーの原因を特定するための背景として考えられるすべてのものです。もちろん、役立つかもしれない他の情報を提供します。よろしくお願いします。

私はCoreDataを初めて使用し、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"];

出力に「変更可能なセットの割り当て前」というメッセージが表示され、その後に

2013-01-23 03:27:14.898 Grocery Manager [6431:11603]initAndFillItemLocationsTableはCreamCheeseという名前のアイテムを取得しました2013-01-2303:27:14.899 Grocery Manager [6431:11603]可変セット割り当ての前2013-01-23 03:27:14.901 Grocery Manager [6431:11603] *キャッチされなかった例外'NSUnknownKeyException'、理由:'[valueForUndefinedKey:]:エンティティGroceryItemsは、キー「hasLocations」のキー値コーディングに準拠していません。*まずスローコールスタック:(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コーディングプログラミングガイドを読み、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」のプロパティです。フェッチ要求は、「hasLocations」メソッドに応答しない「GroceryItems」オブジェクトの配列を返します。

また、通常、CoreDataアクセサーメソッドを実装する必要はありません。これらは実行時に動的に作成されます。

于 2013-01-24T07:41:38.387 に答える