保存 NSManagedObjectContext 导致 UITableView 单元格消失

发布于 2024-10-18 20:53:47 字数 661 浏览 3 评论 0原文

我遇到以下问题。

我正在使用 CoreData 和 Apple Recipes 示例作为指南编写 RSS 阅读器。我有一个刷新按钮,可以重新下载 RSS 并使用 NSFetchRequest 验证是否有新数据。一旦我完成对元素的检查,我就会通过 NSManagedObjectContext 保存方法提交更改。

上下文保存后,tableView消失了!

然后我决定在 tableView 上调用 reloadData 以反映更改。因此,保存 NSManagedObjectContext 后,我​​调用:

[self performSelectorOnMainThread:@selector(updateTableItems) withObject:nil waitUntilDone:NO];

-(void) updateTableItems {
    [self.tableView reloadData];
}

此操作会导致单元格在滚动时删除数据,当我弹出视图并返回时,我会看到所有更改,一切都很好。

我还在其中一个线程中读到,我应该使用 NSFetchedResultsController 并确保 UITableView 是委托,与上一个问题相同。

我做错了什么? 为什么我看不到发生的变化? 为什么单元格的内容被删除?

谢谢!

I'm having the following issue.

I'm writing a RSS reader using CoreData and Apple Recipes example as a guide. I have a refresh button that re-downloads the RSS and verify using NSFetchRequest if there is new data. Once I finish going over the elements I commit the changes via the NSManagedObjectContext save method.

After the context save, the tableView disappears!

I then decided to call reloadData on the tableView to reflect the changes. So, once the NSManagedObjectContext is saved I call:

[self performSelectorOnMainThread:@selector(updateTableItems) withObject:nil waitUntilDone:NO];

-(void) updateTableItems {
    [self.tableView reloadData];
}

This action causes the cell to delete the data while scrolling, when I pop the view and go back, I see all the changes and everything is okay.

I also read in one of the threads that I should use NSFetchedResultsController and make sure the UITableView is the delegate, same issue as the previous one.

What am I doing wrong ?
Why can't I see the changes in place?
Why the cell's content is being deleted?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好多鱼好多余 2024-10-25 20:53:47

听起来您正在单独的线程上使用两个或多个上下文。您在后台线程上下文上提交保存,但不将更改与连接到前端线程上的 UI 的上下文合并。这会导致 UI 上下文与存储不同步,从而导致滚动时表行消失。

当您通过离开视图弹出控制器时,上下文将被释放,这样当您第二次返回视图时,您将拥有一个了解存储更改的新上下文。

为了防止出现此问题,请在保存后台上下文后立即在前台上下文上调用 refreshObject:mergeChanges:。让前端上下文从后台上下文注册 NSManagedObjectContextDidSaveNotification

It sounds like you are using two or more context on separate threads. You commit the save on the background thread context but don't merge the changes with the context connected to the UI on the front thread. This causes the UI context to come out of sync with the store which cause table rows to disappear when you scroll.

When you pop the controller by leaving the view, the context is deallocated such that when you go back to the view a second time, you have a new context aware of the changes to the store.

To prevent this problem, call refreshObject:mergeChanges: on the front context immediately after you save the background context. Have the front context register for a NSManagedObjectContextDidSaveNotification from the background context

是你 2024-10-25 20:53:47

我也遇到过类似的问题,这让我发疯。基本上在我的代码中,有大量竞争线程试图同时更新相同的数据(表视图背后的数据),我认为这会导致 UITableView “爆炸”并且其委托方法停止触发。 (您可以通过将 NSLog 添加到委托方法中来证明这一点)。

它完全随机发生,并且很难复制。

我尝试了各种方法来解决这个问题,但似乎唯一能可靠地确保它不会发生的事情是每次数据更改时完全重新创建我的 UITableView ,如下所示。 (所以基本上在你调用 [self.tableView reloadData] 的地方用下面的代码进行更改)

// The UITableView may in rare circumstances all of a sudden failed to render 
// correctly. We're not entirely sure why this happens but its something to 
// do with multiple threads executing and updating the data behind the view 
// which somehow causes the events to stop firing.  Resetting the delegate and 
// dataSource to self isn't enough to fix things however so we have to 
// completely recreate the UITableView and replace the existing one.

UITableView* tempTableView = [[[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 387)] autorelease];
tempTableView.separatorColor = [UIColor grayColor];
tempTableView.backgroundColor = [UIColor clearColor];

if (self.tableView != nil)
{
    [tempTableView setContentOffset:self.tableView.contentOffset animated:NO];
}

tempTableView.delegate = self;
tempTableView.dataSource = self;
[tempTableView reloadData];  

 if (self.tableView != nil) {
     [self.tableView removeFromSuperview];
     self.tableView = nil;
 }

 [self.view addSubview:tempTableView];
 self.tableView = tempTableView;

我知道这不是理想的修复方法,也不能真正解释问题,但我认为这是一个 iOS 错误。不过,欢迎任何其他意见。

I have been having a similar issue and it was driving me crazy. Basically in my code there are loads of competing threads trying to update the same data at the same time (the data behind the table view) and I think this some how causes the UITableView to "blow up" and its delegate methods stop firing. (You can prove this by adding NSLog's into the delegate methods).

It happens totally randomly and is really difficult to replicate.

I tried all sorts to fix this but the only thing that seems to reliably ensure that it can't happen was completely recreating my UITableView everytime the data changed as below. (So basically change everywhere where you call [self.tableView reloadData] with the following)

// The UITableView may in rare circumstances all of a sudden failed to render 
// correctly. We're not entirely sure why this happens but its something to 
// do with multiple threads executing and updating the data behind the view 
// which somehow causes the events to stop firing.  Resetting the delegate and 
// dataSource to self isn't enough to fix things however so we have to 
// completely recreate the UITableView and replace the existing one.

UITableView* tempTableView = [[[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 387)] autorelease];
tempTableView.separatorColor = [UIColor grayColor];
tempTableView.backgroundColor = [UIColor clearColor];

if (self.tableView != nil)
{
    [tempTableView setContentOffset:self.tableView.contentOffset animated:NO];
}

tempTableView.delegate = self;
tempTableView.dataSource = self;
[tempTableView reloadData];  

 if (self.tableView != nil) {
     [self.tableView removeFromSuperview];
     self.tableView = nil;
 }

 [self.view addSubview:tempTableView];
 self.tableView = tempTableView;

I know this isn't the ideal fix and doesn't really explain the issue but I think this is an iOS bug. Would welcome any other input however.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文