此应用程序将ARC和Core Data与SQLite数据库一起使用。在OSX 10.8上使用Xcode 4.6开发。该数据库包含许多实体,其中几个实体处于父/子关系中。一切都很好,除了涉及父/子关系中两个实体的情况,它们与其他实体不同,因为它们包含数值属性,这些属性是对这两个实体的其他属性执行的数学运算的结果。
子实体包含属性A,B和C(其中C = A * B)。 父实体包含属性X(其中X =其子C的总和)。
数据在同一视图中以两个NSTableView显示。我使用绑定来填充表。当我单击一个单元格来修改B时,C应该立即在同一个表中更新,而X在另一个表中更新。当我添加或删除孩子时,X也应该立即更新。
有两个问题。
当我修改B时,C立即更新,但X不是。当我添加或删除子项时,X也不会更新。为了更新X,我需要保留记录并在表格中选择另一个(然后我可以看到先前选择的记录的X得到更新)。
退出应用程序时,C和X的修改值不会写入数据库文件中。
我的代码中遗漏了什么?这是我的托管对象类。我修改了属性和类名以使其更清晰。
// header of parent
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Child;
@interface Parent : NSManagedObject
@property (nonatomic, retain) NSDecimalNumber * parent_X;
@property (nonatomic, retain) NSSet *children;
@end
@interface Parent (CoreDataGeneratedAccessors)
- (void)addChildrenObject:(NSManagedObject *)value;
- (void)removeChildrenObject:(NSManagedObject *)value;
- (void)addChildren:(NSSet *)values;
- (void)removeChildren:(NSSet *)values;
@end
// implementation of parent
#import "Parent.h"
@implementation Parent
@dynamic parent_X;
@dynamic children;
- (void)addChildrenObject:(NSManagedObject *)value {
NSSet *s = [NSSet setWithObject:value];
[self willChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:s];
[[self primitiveValueForKey:@"children"] addObject:value];
[self didChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:s];
}
- (void)removeChildrenObject:(NSManagedObject *)value {
NSSet *s = [NSSet setWithObject:value];
[self willChangeValueForKey:@"children" withSetMutation:NSKeyValueMinusSetMutation usingObjects:s];
[[self primitiveValueForKey:@"children"] removeObject:value];
[self didChangeValueForKey:@"children" withSetMutation:NSKeyValueMinusSetMutation usingObjects:s];
}
- (void)addChildren:(NSSet *)values {
NSSet *s = [NSSet setWithObject:values];
[self willChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:s];
[[self primitiveValueForKey:@"children"] addObject:values];
[self didChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:s];
}
- (void)removeChildren:(NSSet *)values {
NSSet *s = [NSSet setWithObject:values];
[self willChangeValueForKey:@"children" withSetMutation:NSKeyValueMinusSetMutation usingObjects:s];
[[self primitiveValueForKey:@"children"] removeObject:values];
[self didChangeValueForKey:@"children" withSetMutation:NSKeyValueMinusSetMutation usingObjects:s];
}
- (NSDecimalNumber *)parent_X {
return [self valueForKeyPath:@"children.@sum.child_C"];
}
@end
// header of child
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Parent;
@interface Child : NSManagedObject
@property (nonatomic, retain) NSDecimalNumber * child_A;
@property (nonatomic, retain) NSDecimalNumber * child_B;
@property (nonatomic, retain) NSDecimalNumber * child_C;
@property (nonatomic, retain) Parent *parent;
@end
// implementation of child
#import "Child.h"
#import "Parent.h"
@implementation Child
@dynamic child_A;
@dynamic child_B;
@dynamic child_C;
@dynamic parent;
- (void)awakeFromInsert {
[super awakeFromInsert];
[self setValue:@50.00f forKey:@"child_A"];
[self setValue:@1.00f forKey:@"child_B"];
}
-(NSDecimalNumber *)child_C {
return [[self child_A] decimalNumberByMultiplyingBy:[self child_B]];
}
@end
答案 0 :(得分:0)
在您的代码中,您似乎在添加或删除对象后未保存到CoreData
。我不确定Xcode 4.6,但在4.6.3中,Xcode自动填充以下方法:
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
你有没有它,你只是忘了打电话给它?如果您没有填充,则需要添加它以将更改保存到CoreData
。
或者,您只需从- (BOOL)save:(NSError **)error
致电NSManagedObjectContext
。