- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的应用程序有两个选项卡栏...每个选项卡栏都将用户带到一个向他显示项目列表的 TableView Controller 。第一个 View 允许用户在数据库中记录条目。另一个选项卡/ View 从数据库读取数据并将这些项目呈现给用户,但是,不会从第二个 View 对 coreData/持久存储进行任何更新。
当我通过第一个 View Controller 添加新项目时,它完美地显示在 View 中。但是,一旦我点击另一个选项卡栏以查看该 View Controller 中出现的新项目,我就会收到下面列出的错误,并且新添加的项目不会出现...注意:如果我停止应用程序并重新加载/重新运行它,然后首先点击第二个选项卡栏,新项目显示正常,所以我知道模型正在正常更新。
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1046
2011-10-20 20:56:15.117 Gtrac[72773:fb03] CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (3), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)
来自委托(delegate)应用程序的代码,其中 ManagedObjectContext 被传递到两个 viewController。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// get a point to the master database context
NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
// Handle the error.
}
// create tab bar controller and array to hold each of the tab-based view controllers that will appear as icons at bottom of screen
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:5];
//
// setup first tab bar item
//
//
// alloc the main view controller - the one that will be the first one shown in the navigation control
RootViewController *rootViewController = [[RootViewController alloc] initWithTabBar];
// Pass the managed object context to the view controller.
rootViewController.managedObjectContext = context;
// create the navigation control and stuff the rootcontroller inside it
UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
// set the master navigation control
self.navigationController = aNavigationController;
// add the navigaton controller as the first tab for the tab bar
[localControllersArray addObject:aNavigationController];
[rootViewController release];
[aNavigationController release];
//
// setup the other tab bar
//
//
// alloc the view controller
vcSimulator *vcSimulatorController = [[vcSimulator alloc] initWithTabBar];
UINavigationController *blocalNavigationController = [[UINavigationController alloc] initWithRootViewController:vcSimulatorController];
// Pass the managed object context to the view controller.
vcSimulatorController.managedObjectContext = context;
// add this controller to the array of controllers we are building
[localControllersArray addObject:blocalNavigationController];
// release these guys, they are safely stored in the array - kill these extra references
[blocalNavigationController release];
[vcSimulatorController release];
//
//
// ok, all the tab bars are in the array - get crackin
//
//
// load up our tab bar controller with the view controllers
tabBarController.viewControllers = localControllersArray;
// release the array because the tab bar controller now has it
[localControllersArray release];
[window addSubview:[tabBarController view]];
[window makeKeyAndVisible];
return YES;
When I add a new item via the first viewcontroller, it shows up perfectly in the view. However, as soon as I tap on the other tab bar to see the new item appear in that viewcontroller, I get the error listed above, and the newly added item does not appear... Note: if I stop the app and reload/re-run it, and start by tapping the 2nd tabbar, the new item shows up fine, so I know the model is being updated fine.
Here are the tableview delegate methods from the 2nd view controller.
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(@">>> Entering %s [Line %d] ", __PRETTY_FUNCTION__, __LINE__);
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSLog(@">>> Entering %s [Line %d] ", __PRETTY_FUNCTION__, __LINE__);
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
如果您能提供任何帮助,我们将不胜感激。
我搜索了该网站并发现了许多此错误的实例,但似乎没有一个非常合适。我还看到一些引用资料推断我看到的这个错误实际上是 Apple 代码中的一个已知错误...
* 更新信息 *
我已经返回并在代码中设置断点,并使用这些附加信息编辑原始问题。当用户向数据库添加新项目时,他将从 Root View 转换到列表类(class) View 。添加事务工作完美,并且 listCourses View UITableView 完美更新。
当我单击也从同一核心数据模型读取数据的另一个 View 时,它的 View Controller 会运行以下序列,但永远不会结束将新项目添加到 TableView 中。这是它经历的顺序。
模拟器VC:
- controllerWillChangeContent which runs...
[self.tableView beginUpdates];
- didChangeObject
..with message: NSFetchedResultsChangeUpdate
..which ran:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
- controllerDidChangeContent:
[self.tableView endUpdates];
另一个效果很好的 View Controller ,在将记录添加到数据库后立即执行此序列。
列出 VC 类(class):
- didChangeSection
...with message: NSFetchedResultsChangeInsert
...which ran:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
- didChangeObject
..with message: NSFetchedResultsChangeInsert
..which ran:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
为什么一个 View Controller 收到 NSFetchedResultsChangeInsert 消息,而另一个 View Controller 却没有?
以下是来自错误 View Controller 的委托(delegate)方法。
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
NSLog(@">>> Entering %s [Line %d] ", __PRETTY_FUNCTION__, __LINE__);
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(@">>> Entering %s [Line %d] ", __PRETTY_FUNCTION__, __LINE__);
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
//[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
//[tableView reloadData];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
// Reloading the section inserts a new row and ensures that titles are updated appropriately.
// [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
}
NSLog(@"vc>>> about to reload data");
// [self.tableView reloadData];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSLog(@">>> Entering %s [Line %d] ", __PRETTY_FUNCTION__, __LINE__);
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
// [self.tableView reloadData];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
NSLog(@">>> Entering %s [Line %d] ", __PRETTY_FUNCTION__, __LINE__);
[self.tableView endUpdates];
}
谢谢,菲尔
最佳答案
UITableView 健全性检查的工作原理如下:
在 [self.tableView beginUpdates] 行; tableView 调用您的 tableView:numberOfRowsInSection: 委托(delegate)方法,该方法似乎返回 3。 在 [self.tableView endUpdates] 行;它再次调用它,它似乎返回 4。因此,tableView 希望您在这两行之间插入 1 行。事实上,没有插入任何行,因此 tableView 断言失败。 (您可以在断言消息中看到预期行数和实际行数)。
从 3 行增加到 4 行表明您的 NSFetchedResultsController 正确地注意到新插入的核心数据项。您需要做的是在 Controller 的开头放置一个断点:didChangeObject:atIndexPath:forChangeType: 方法,并在插入项目后切换到第二个选项卡时单步执行它。您应该看到正在执行的 switch 语句的 NSFetchedResultsChangeInsert: 情况,但这显然没有发生。
希望您能够找出插入未发生的原因 - 否则请返回并让我们知道您在逐步执行此方法时实际看到的内容。
编辑添加:
好的,所以当您切换到该选项卡时,会调用第二个 View Controller 中的 NSFetchedResultsController 委托(delegate)方法,而不是在选项卡 1 上插入新项目时立即调用。这意味着第二个 View Controller 看不到插入(其中应该立即发生),并且实际上是响应稍后切换到选项卡 2 时发生的其他一些核心数据更新通知。获取的结果 Controller 正在使用 beginUpdates 行中的过时信息(这里的结果集中实际上有 4 项,而不是3)。当它到达 endUpdates 行时,它已经刷新了其获取并发现了意外的插入。
NSFetchedResultsController 委托(delegate)方法实际上旨在在您进行更改且 Controller View 可见时就地更新 UI。在您的情况下,您正在进行更改,然后显示新的 View Controller 。您真正应该使用的模式是在 Controller 2 的 viewWillAppear 方法中刷新 tableview。类似这样的事情应该可以做到:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSError *error = nil;
[resultsController performFetch:&error]; // Refetch data
if (error != nil) {
// handle error
}
[self.tableView reloadData];
}
这将确保每当您切换到选项卡 2 时,它都会使用模型中的新数据。
关于iphone - CoreData 错误让我发疯... CoreData : Serious application error. 从 NSFetchedResultsController 委托(delegate)捕获的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7844326/
该程序是一个显示媒体的系统:图像、视频并在它们之间不断交替。问题是使用增加内存:编程运行30分钟后,消耗1.2GB内存 我不太清楚我能做什么,我相信内存消耗增加的原因是递归(函数调用自身)或者每次给出
看完this关于为什么 google/facebook 等添加无法解析的内容的问题,例如: while(1); for(;;); &&&START&&& ... &&&END&&& 1 和 3 组合
我正在完成我的 Core Data 应用程序,并开始最终测试。 Everyfing 工作正常,除了一件事,它是随机发生的,而且我无法重现它。 这是日志(使用 NSZombieEnabled): 201
我正在使用 Appcelerator 并想做一些视频处理。我遇到了 Seriously.js,发现您可以在“节点”管道中进行一些令人印象深刻的图像和视频流操作。因此,在进行这项工作的应用加速器部分之前
我正在尝试调整 Canvas DOM 元素中相机显示的大小。我尝试过使用事件监听器,并且能够毫无问题地调整 Canvas 大小。然而,相机的视频源不会更新其大小,它保持与初始化时相同。为了使其工作,我
背景:我有一个模仿 fgets(character, 2, fp) 的小例程,只是它从字符串而不是流中获取字符。 newBuff 是动态分配的字符串,作为参数传递,字符被声明为 char charac
Linux的“手动关闭”警告(SVr4、4.3BSD,POSIX.1-2001): Not checking the return value of close() is a common but n
我目前正在调查我的 Android 应用程序的垃圾收集问题,我很想知道 GC_FOR_ALLOC 是否表明存在比其他 GC 消息(例如 GC_CONCURRENT)更大的问题。 据我了解,GC_CON
这个问题在这里已经有了答案: Why should casting be avoided? [closed] (14 个答案) 关闭 9 年前。 来自 http://www.stroustrup.c
我正在开发一个应用程序,允许用户管理一些单独的数据点。我的用户想要做的事情之一是“删除”,但这意味着什么? 对于网络应用程序来说,向用户提供严格删除或使用“垃圾”系统的选项是否更好? 在“严重删除”下
好的, 这是我在 stackoverflow 上发表的第一篇文章。几个小时以来,我一直在用头撞墙。我讨厌输入问题;你可以相信我已经竭尽全力地尝试自己解决这个问题。我对以下错误进行了一些研究,但仍然无法
我网站的管理部分有一堆非常慢的报告生成脚本,它们在生成时逐行echo 输出。要立即将此输出刷新到浏览器,而不是用户必须等待几分钟才能看到任何响应,我们有 output_buffering禁用,我们调用
嗨,我要崩溃了, 当我试图在后台将 1000 条记录插入数据库时,出现以下异常:CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。 这通常是 的观察者中的错误 NSMa
我在开发我的 iPhone 应用程序时遇到了重大问题。 这是完整的错误: CoreData: error: Serious application error. Exception was caug
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 我们不允许提出有关书籍、工具、软件库等方面的建议的问题。您可以编辑问题,以便用事实和引用来回答它。 关闭
有一个包含图像的容器组件。这个容器应该是 后面不同容器组件中的文本。两个容器组件距离 Root 元素的深度相同。解释确切的结构有点复杂。 问题的要点是 zIndex 在 iOS 上受尊重,但在 And
(不,这不是家庭作业,我只是发现了这个错误并认为在这里分享它可能会有用) import java.util.List; public class BubbleSorter { public >
目标是将一系列视网膜图像转换为单个视频。 下面的两个函数负责将 UIImage 写入 AVAssetWriterInputPixelBufferAdaptor。它们起作用了,并且代码从图像中生成了看似
我正在尝试在 Meteor 应用程序中使用 Seriously.js 库 ( https://github.com/brianchirls/Seriously.js/ )。我已将该库放在我的 mete
我正在 iOS 上编写一个程序,我正面临这个错误: 2015-11-06 10:57:24.289 NETFNET[2503:976392] CoreData: error: Serious appl
我是一名优秀的程序员,十分优秀!