0

这个应用程序使用 ARC 和 Core Data 以及 SQLite 数据库。在 OSX 10.8 上使用 Xcode 4.6 开发。数据库包含许多实体,其中一些实体具有父/子关系。一切都很好,除了涉及父/子关系中的两个实体的情况,这与其他实体不同,因为它们包含数字属性,这些属性的值来自对这两个实体的其他属性执行的数学运算。

子实体包含属性 A、B 和 C(其中 C = A * B)。父实体包含属性 X(其中 X = 其子实体 C 的总和)。

数据呈现在同一个视图上的两个 NSTableView 中。我使用绑定来填充表格。当我单击一个单元格来修改 B 时,C 应该立即在同一个表中更新,而 X 在另一个表中。当我添加或删除一个孩子时,X 也应该立即更新。

有两个问题。

  1. 当我修改 B 时,C 会立即更新,但 X 不会。当我添加或删除一个孩子时,X 也不会更新。为了更新 X,我需要离开记录并在表中选择另一个记录(然后我可以看到先前选择的记录的 X 已更新)。

  2. 在退出应用程序时,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
4

1 回答 1

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.

于 2013-08-20T09:08:49.157 回答