gpt4 book ai didi

ios - 使用核心数据执行此操作的 "right"方法是什么(更新多个实体)

转载 作者:行者123 更新时间:2023-11-29 01:29:11 25 4
gpt4 key购买 nike

我是 Core Data 的新手。我有两个实体:USERIOU

// User.h
@property (nullable, nonatomic, retain) NSString *name;
@property (nullable, nonatomic, retain) NSSet<NSManagedObject *> *ious;

// Iou.h
@property (nullable, nonatomic, retain) NSDecimalNumber *amount;
@property (nullable, nonatomic, retain) NSDate *date;
@property (nullable, nonatomic, retain) NSString *iouDescription;
@property (nullable, nonatomic, retain) User *user;

在 View Controller 中,我使用谓词来获取属于用户的 ious,然后使用它来获取用户的名称。然后,我显示该用户的姓名以及她的 ious 列表。

// PersonViewController.m
// Fetch Request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Iou"];

// Predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"user.name", self.userName];
[fetchRequest setPredicate:predicate];

// Execute fetch request
NSError *error = nil;

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController.delegate = self;

[self.fetchedResultsController performFetch:&error];

Iou *iou = self.fetchedResultsController.fetchedObjects.lastObject;
self.user = iou.user;

接下来,我的客户可以点击借条并编辑借条和用户。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Iou *iou = [self.fetchedResultsController objectAtIndexPath:indexPath];
personEditViewController.user = self.user;
personEditViewController.iou = iou;
personEditViewController.managedContext = self.managedContext;
[[self navigationController] pushViewController:personEditViewController animated:YES];
}

以下是我编辑 USER 实体和 IOU 实体的方法。

// PersonEditViewController.m
self.user.name = self.nameField.text;

// Description
self.iou.iouDescription = self.descriptionField.text;

// Date
UIDatePicker *datePicker = (UIDatePicker *)self.dateField.inputView;
self.iou.date = datePicker.date;

// Save
NSError *error;
[self.iou.managedObjectContext save:&error];

我使用 NSFetchedResultsController 来处理 UITableView。如果我更改 IOU 属性,我会得到正确的行为。我得到 NSFetchedResultsChangeMove;但是,如果我还更新了 USER,我会得到 NSFetchedResultsChangeDelete。如果我重新启动,数据看起来很好,所以它只发生在 View 中。

我搜索了一些SO问题,但我仍然不明白。有什么简单的模式可以使用,这样它每次都会有效。

我考虑过不使用NSFetchedResultsController,而是依靠带有UITableView的旧式NSArray。在这种情况下,每次我对记录进行增删改查时,它都会从数据库中重新获取记录,我将使用 fetchedResultsController.fetchedObjects

最佳答案

如果修改 User 对象的 name 属性,它将不再匹配谓词 - 因此 FRC 将触发 delete 以删除 TableView 。 (请注意,您可能希望删除所有其他行,因为它们也不再满足谓词,但 FRC 仅重新评估那些已更新的 IOU)。

如果您想避免这种情况,请修改您的获取结果 Controller 代码以首先获取与谓词匹配的 User 对象,然后修改 FRC 谓词以测试是否 IOU 属于这些用户中的任何一个:

// PersonViewController.m
NSError *error = nil;
NSFetchRequest *userFetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"User"];
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"name", self.userName];
userFetchRequest.predicate = userPredicate;
NSArray *matchingUsers = [self.managedContext executeFetchRequest:userFetchRequest error:&error];
// Fetch Request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Iou"];

// Predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K IN %@", @"user", matchingUsers];
[fetchRequest setPredicate:predicate];

// Execute fetch request
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController.delegate = self;

[self.fetchedResultsController performFetch:&error];

Iou *iou = self.fetchedResultsController.fetchedObjects.lastObject;
self.user = iou.user;

由于 FRC 的谓词是基于 User 对象本身,而不是它的任何属性,您可以修改这些属性而不会导致其 IOU 无法满足FRC 的谓词。

关于ios - 使用核心数据执行此操作的 "right"方法是什么(更新多个实体),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33633767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com