我必须在名为Person and Goal的核心数据中使用NSManagedObjects。他们有多对多的关系。我有一个表视图控制器,显示与给定的Person对象关联的Goal对象。此tableview控制器的目的是允许您点击给定Goal单元格内的“加号”按钮,并将“点”从Person对象传输到Goal对象。
用于执行此操作的获取请求是:
NSManagedObjectContext *context = self.context;
if (self.selectedItemID) {
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Goal"];
request.sortDescriptors = [NSArray arrayWithObjects:
[NSSortDescriptor sortDescriptorWithKey:@"name"
ascending:YES],
nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(self IN %@) AND (completed == %@)",
person.goals,
[NSNumber numberWithBool:NO]];
if (predicate) [request setPredicate:predicate];
//Note: |self.frc| is defined in the super class
self.frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:nil];
self.frc.delegate = self;
这是每个目标单元格中“加号”按钮调用的方法:
- (IBAction)modifyPointsForGoal:(UIButton *)sender {
//Get a reference to the |Goal| object for the button's cell. The view hierarchy may not be fixed,
//so traverse up the view hierarchy until a UITableViewCell is found and get its NSIndexPath
UIView *view = sender;
while (![view isKindOfClass:[GoalForPersonCell class]]) view = view.superview;
GoalForPersonCell *cell = (GoalForPersonCell *)view;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
//Get reference to |Goal| and |Person| object
Goal *cellsGoal = (Goal *)[self.frc objectAtIndexPath:indexPath];
NSManagedObjectID *cellsGoalObjectID = cellsGoal.objectID;
Goal *goal = (Goal *)[self.context existingObjectWithID:cellsGoalObjectID
error:nil];
Person *person = self.person;
//Using the button tag numbers, increment/decrement values as needed
gFPVCSenderButtonType buttonType = (int)sender.tag;
switch (buttonType) {
case giveAdd:
[goal incrementValueBalanceWithDefaults];
break;
case giveSubtract:
[goal decrementValueBalanceWithDefaults];
break;
case bankAdd:
// decrementBalanceForGoalType returns FALSE if there are insufficient funds
if ([person decrementBalanceUsingGoal:goal])
[goal incrementValueBalanceWithDefaults];
break;
case bankSubtract:
// decrementValueBalance returns FALSE if there are insufficient funds
if ([goal decrementValueBalanceWithDefaults])
[person incrementBalanceUsingGoal:goal];
break;
default:
break;
}
}
每个单元格中的按钮按预期工作 - 值从Person对象获取并提供给单元格表示的Goal对象。我遇到的问题是对Person对象的更改被写入持久性存储,但对Goal对象的更改则不会。因此,当重新启动应用程序时,目标对象似乎没有变化。
我使用SQL浏览器来验证更改是否未写入磁盘。如果您在关闭应用程序之前查看其他VC中的Goal对象,则可以看到对象对象的更改 - 就好像对象的更改被写入上下文一样,但是它们不再持续存在,并且仅针对特定对象对象
我尝试使用XCode重新生成NSManagedObject子类,但它没有解决问题。我完全被难倒了,经过七个小时的努力弄清楚,我已经知道了。
答案 0 :(得分:1)
将更改保存到持久存储中:
NSError *err= nil;
[managedObjectContext save:&err];
创建后使用FRC(使用一次):
[FRC setAutomaticallyPreparesContent:<#(BOOL)#>];
[RFC setAutomaticallyRearrangesObjects:<#(BOOL)#>];
答案 1 :(得分:0)
最终问题出在我的实体的NSManagedObject子类上。
我没有将自定义方法添加到Xcode从我的数据模型创建的NSManaged子类中,而是使用了一种技术,而我使用XCode创建了NSManagedObject子类,然后再次将其子类化以添加我的自定义方法。我这样做是因为它允许您更改实体并使用XCode重新创建NSManagedObject子类,而不会破坏您编写的所有自定义方法。
这也让我做了一件坏事:
_Goal.m
#import "_Goal.h"
@implementation _Goal
@dynamic moneyBalance;
@end
Goal.h
#import "Goal.h"
@end
Goal.m
@synthesize moneyBalance = _moneyBalance
-(NSManagedObject *)setMoneyBalance {
//Custom setter code for boundry checking
}
因为我按照我的方式对事物进行了子类化,所以编译器没有抛出错误/警告告诉我,我基本上是通过@synthesizing重新定义(在这种情况下覆盖)moneyBalance属性。这允许我的自定义方法工作,但使CoreData不可见更改。
一旦我删除了@synthesize和自定义设置器,一切都恢复了。