0

我一遍又一遍地讨论这个问题,我一生都无法弄清楚为什么通过 setValue:forKey: 分配关系不起作用。我的方法如下。

-(void)saveNewCartItemName:(NSString *)name Price:(float)price Qty:(int)qty Tax:(int)tax inCart:(NSDate *)cartDate{
    NSManagedObject *newItem = [NSEntityDescription insertNewObjectForEntityForName:@"Item"
                                                             inManagedObjectContext:self.appDelegate.managedObjectContext];

    NSFetchRequest *query = [[NSFetchRequest alloc] initWithEntityName:@"Cart"];
    NSLog(@"cartDate = %@", cartDate);
    [query setPredicate:[NSPredicate predicateWithFormat:@"cartDate = %@", cartDate]];
    NSError *error;
    NSMutableArray *queryResults = [[self.appDelegate.managedObjectContext executeFetchRequest:query error:&error] mutableCopy];
    NSLog(@"queryResults count = %d", [queryResults count]);
    if ([queryResults count] == 1) [newItem setValue:[queryResults objectAtIndex:0] forKey:@"cartThatHasItem"];
    [newItem setValue:name forKey:@"itemName"];
    [newItem setValue:[NSNumber numberWithFloat:price] forKey:@"itemPrice"];
    [newItem setValue:[NSNumber numberWithInt:qty] forKey:@"itemQty"];
    [newItem setValue:[NSNumber numberWithInt:tax] forKey:@"itemTax"];

    [self.appDelegate.managedObjectContext save:&error];
}

它每次崩溃的行是:

if ([queryResults count] == 1) [newItem setValue:[queryResults objectAtIndex:0] forKey:@"cartThatHasItem"];

我的 NSLog 显示有一个 NSManagedObject 可以分配关系,并且我仔细检查了 forKey 中的名称:没有拼写错误。Xcode 告诉我的只是它在我的控制台上打印出“(null)”,然后在下一行告诉我“libc++abi.dylib: terminate called throwing an exception”。

为什么会崩溃?我该如何解决?

更新:这是整个错误信息。

2012-07-03 18:28:57.844 appName[3063:11603] (null)
libc++abi.dylib: terminate called throwing an exception
(lldb)
4

2 回答 2

1

我看到的一个问题是您没有检查错误对象。如果发生错误,那么 queryResults 可能会 = nil,并且您随后尝试检查 count 将使您崩溃。至少检查 nil 条件:

NSMutableArray *queryResults = [[self.appDelegate.managedObjectContext executeFetchRequest:query error:&error] mutableCopy];

if( queryResults == nil ) return; // Or better yet check the value of Error.
于 2012-07-03T23:54:56.423 回答
1

好吧,没有足够的调试信息......因为你只需要检查是否queryResults有一个对象,所以我会使用

[newItem setValue:[queryResults lastObject] forKey:@"cartThatHasItem"];

代替

if ([queryResults count] == 1) [newItem setValue:[queryResults objectAtIndex:0] forKey:@"cartThatHasItem"];

不确定它是否能解决您的问题,但值得一试。:)


编辑

通过您的问题标题“... for many-to-many relationship”cartThatHasItem ,我想知道&之间的关系是Cart什么?如果是多对一或多对多,则cartThatHasItem的数据类型为NSSet。所以,你需要包装[queryResults objectAtIndex:0]'喜欢

[newItem setValue:[NSSet setWithObject:[queryResults objectAtIndex:0]]
           forKey:@"cartThatHasItem"];

,或者你可以使用

[newItem addCartThatHasItem:[queryResults objectAtIndex:0]]

反而。(addCartThatHasItem:将在您生成购物车模型时自动添加。)


编辑 2

Cart 模型应该是这样的:

@interface Cart : NSManagedObject

//...
@property (nonatomic, retain) NSSet *cartThatHasItem;

@end

@interface Cart (CoreDataGeneratedAccessors)

//...
- (void)addCartThatHasItemObject:(CartThatHasItem *)value;
- (void)removeCartThatHasItemObject:(CartThatHasItem *)value;
- (void)addCartThatHasItem:(NSSet *)values;
- (void)removeCartThatHasItem:(NSSet *)values;

@end

如果您正确生成模型。

于 2012-07-03T22:56:04.397 回答