gpt4 book ai didi

ios - 带有 NSFetchedResultsController 错误的 moveRows

转载 作者:行者123 更新时间:2023-12-01 17:18:22 25 4
gpt4 key购买 nike

我在这里的某个地方有一个错误,我找不到它,所以我希望你敏锐的眼睛会!

我正在使用带有 tableView 的 FRC。 FRC 是按 keyPath 排序的部分,然后按“displayOrder”排序 - 通常。

每个部分中的详细信息“displayOrder”从 1 开始,因此当我插入一个项目时,在另一种方法中,它会转到该部分的索引 0。

我想遍历受影响的部分并从 1 开始重新分配“displayOrder”。

在重新订购期间,代码适用于:
只要重新排序的单元格向上移动而不是向下移动,就可以在任何部分重新排序。

代码不适用于...单击单元格但不移动它..代码由于某种原因更改了顺序,从而更改了单元格的顺序。 - 当我单击一个单元格时,它与同一部分中的其他单元格一起重新排序。

我曾经有这个工作,我不知道发生了什么。

谢谢你的帮助。

-编辑-

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath

NSError *error = nil;

NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];

TheDetail *fromThing = [self.fetchedResultsController objectAtIndexPath:fromIndexPath];
TheDetail *toThing = [self.fetchedResultsController objectAtIndexPath:toIndexPath];

NSPredicate *catetgoryPredicate = [NSPredicate predicateWithFormat:@"relationshipToTheCategory.name == %@", fromThing.relationshipToTheCategory.name];

NSMutableArray *allThings = [[[self.fetchedResultsController fetchedObjects] filteredArrayUsingPredicate:catetgoryPredicate] mutableCopy];

NSPredicate *fromPredicate = [NSPredicate predicateWithFormat:@"relationshipToTheSection.name == %@", fromThing.relationshipToTheSection.name];
NSPredicate *toPredicate = [NSPredicate predicateWithFormat:@"relationshipToTheSection.name == %@", toThing.relationshipToTheSection.name];

[allThings removeObject:fromThing];
[allThings insertObject:fromThing atIndex:toIndexPath.row];

//if the sections are NOT the same, reorder by section otherwise reorder the one section
if (![fromThing.relationshipToTheSection.name isEqual:toThing.relationshipToTheSection.name]) {

//Change the from index section's relationship and save, then grab all objects in sections and re-order
[fromThing setRelationshipToTheSection:toThing.relationshipToTheSection];

if ([context save:&error]) {
NSLog(@"The setting section save was successful!");
} else {
NSLog(@"The setting section save was not successful: %@", [error localizedDescription]);
}

NSMutableArray *fromThings = [[allThings filteredArrayUsingPredicate:fromPredicate]mutableCopy];
NSInteger i = 1;
for (TheDetail *fromD in fromThings) {
[fromD setValue:[NSNumber numberWithInteger:i] forKey:@"displayOrder"];
i++;

}
//reset displayOrder Count, the re-order the other section
i = 1;
NSMutableArray *toThings = [[allThings filteredArrayUsingPredicate:toPredicate]mutableCopy];
for (TheDetail *toD in toThings) {
[toD setValue:[NSNumber numberWithInteger:i] forKey:@"displayOrder"];
i++;

}
} else {
NSMutableArray *fromThings = [[allThings filteredArrayUsingPredicate:fromPredicate]mutableCopy];
NSInteger i = 1;
for (TheDetail *fromD in fromThings) {
[fromD setValue:[NSNumber numberWithInteger:i] forKey:@"displayOrder"];
i++;
}
}
if ([context save:&error]) {
NSLog(@"The save was successful!");
} else {
NSLog(@"The save was not successful: %@", [error localizedDescription]);
}

FRC
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSManagedObjectContext *context = [[self appDelegate]managedObjectContext];

//Construct the fetchResquest
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *detail = [NSEntityDescription entityForName:@"TheDetail" inManagedObjectContext:context];
[fetchRequest setEntity:detail];

//Add predicate
NSString *category = @"1";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"relationshipToTheCategory == %@", category];
[fetchRequest setPredicate:predicate];

//Add sort descriptor
NSSortDescriptor *sortDescriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"relationshipToTheSection.displayOrder" ascending:YES];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"displayOrder" ascending:YES];

NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor2, sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];


//Set fetchedResultsController
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"relationshipToTheSection.name" cacheName:@"Root"];
NSError *error = nil;


self.fetchedResultsController = theFetchedResultsController;
self.fetchedResultsController.delegate = self;
[self.fetchedResultsController performFetch:&error];

return _fetchedResultsController;

新错误
    Section *toSection = [[self fetchedResultsController] sections][[toIndexPath section]];

NSString *toSectionName = [[[toSection objects] lastObject] name];

在这里,我在 IB 中得到错误“没有可见的 @interface 为“DSection”声明选择器“对象”。

最佳答案

  • 不要删除自己作为 NSFetchedResultsController 的代表.这与该类的预期设计背道而驰。如果那是“帮助”,那么它掩盖了一个真正的问题。
  • 请勿调用-performFetch;从这个方法。 NSFetchedResultsController将检测到更改并告诉您的代表。
  • 请勿调用-reloadData从这个方法。让 NSFetchedResultsController 的委托(delegate)方法进行重新排序。
  • 永远,永远,永远捕获核心数据保存的错误。即使你真的不需要在这里保存(这是一个用保存来阻止 UI 的糟糕时机),你应该 总是 捕获错误然后观察结果,否则错误会被隐藏。
  • 不清楚 -save: 是什么是在做。到该保存点为止,您还没有更改任何内容。

  • 所以这是你正在做的很多你不需要做的工作。您正在与框架作斗争并使事情变得更加困难。

    我认为,您的重新排序逻辑比它需要的要复杂得多。看看 NSFetchedResultsController 会有所帮助初始化也是如此。但我猜你有基于 name 的部分然后通过 displayOrder 订购.如果是这种情况,则此代码可能会更清晰,这将使问题更加明显。

    我的问题是,你用断点检查这个吗?当一行没有实际移动时,此代码是否会触发?您是否应该检查一下您的 toIndexPathfromIndexPath是平等的吗?

    更新

    您无需在此处保存上下文。这是一种 UI 方法,保存会导致延迟,从而使 UI 响应缓慢。 稍后保存。

    你不需要在这里运行 NSFetchRequest。这也会影响磁盘并导致 UI 延迟。您需要的每条信息都已经在您的 NSFetchedResultsController 的内存中。 .使用现有的对象关系来检索您做出决策所需的数据。

    来电实体 The*违反 Objective-C 命名约定。像“the”、“is”、“are”这样的词不属于实体或类名。

    考虑这个版本的代码:
    - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
    {
    NSManagedObjectContext *context = [[self fetchedResultsController] managedObjectContext];

    TheDetail *fromThing = [[self fetchedResultsController] objectAtIndexPath:fromIndexPath];
    Section *toSection = [[self fetchedResultsController] sections][[toIndexPath section]];

    NSString *toSectionName = [[[toSection objects] lastObject] name];
    NSString *fromSectionName = [[fromThing relationshipToTheSection] name];
    if ([toSectionName isEqualToString:fromSectionName]) {
    //Same section, easy reorder

    //Move the object
    NSMutableArray *sectionObjects = [[[[self fetchedResultsController] sections][[fromIndexPath section]] objects] mutableCopy];
    [sectionObjects removeObject:fromThing];
    [sectionObjects insertObject:fromThing atIndex:[toIndexPath row]];

    //Reorder
    NSInteger index = 1;
    for (TheDetail *thing in sectionObjects) {
    [thing setValue:@(index) forKey:@"displayOrder"];
    }

    return; //Early return to keep code on the left margin
    }

    NSMutableArray *sectionObjects = [[[[self fetchedResultsController] sections][[fromIndexPath section]] objects] mutableCopy];
    [sectionObjects removeObject:fromThing];

    //Reorder
    NSInteger index = 1;
    for (TheDetail *thing in sectionObjects) {
    [thing setValue:@(index) forKey:@"displayOrder"];
    }

    if ([[toSection numberOfObjects] count] == 0) {
    [fromThing setValue:@(0) forKey:@"displayOrder"];
    //How do you determine the name?
    return;
    }

    sectionObjects = [[toSection objects] mutableCopy];
    [sectionObjects insertObject:fromThing atIndex:[toIndexPath row]];

    //Reorder
    NSInteger index = 1;
    for (TheDetail *thing in sectionObjects) {
    [thing setValue:@(index) forKey:@"displayOrder"];
    }
    }

    没有获取也没有保存。我们只使用内存中的内容,所以它是 非常快速地。除了我留下的评论之一,这应该是 C&P-able。

    关于ios - 带有 NSFetchedResultsController 错误的 moveRows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21000858/

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