Jos*_*hua 6 iphone core-data ios4
我的核心数据模型有两个实体:Author并且Book具有To-Many关系(一个作者 - >多本书).在主视图中,我显示了一个书籍列表,其中每个单元格包含书名和作者姓名.视图也分为几个部分,每个部分标题是作者名称.(注意为"排序描述符"和"sectionNameKeyPath"设置了"author.name")
这是代码(为简洁起见而简化):
- (NSFetchedResultsController *)fetchedResultsController {
if (__fetchedResultsController != nil) {
return __fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"author.name" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"author.name" cacheName:nil] autorelease];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
return __fetchedResultsController;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
Book* book = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", book.name, book.author.name];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[[self.fetchedResultsController sections] objectAtIndex:section] name];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller {
[self.tableView reloadData];
}
Run Code Online (Sandbox Code Playgroud)
现在,如果用户更改作者姓名然后返回主视图,则单元格和部分将显示旧作者姓名.在搜索互联网之后,我发现以下代码修复了单元格中的旧作者姓名问题,但未在章节标题中修复:
- (void)saveAuthorName:(NSString *)newName {
for (Book* book in author.books) {
[book willChangeValueForKey:@"author"];
}
author.name = newName;
for (Book* book in author.books) {
[book didChangeValueForKey:@"author"];
}
// save changes
NSError * error ;
if( ![self.moc save:&error] ) {
// Handle error
}
}
Run Code Online (Sandbox Code Playgroud)
为什么[self.fetchedResultsController sections]还包含旧作者姓名?请帮忙!
本节涉及马库斯的回应#1
嗯,还是有点模糊.你是说分段数不正确吗?
部分的数量没有改变.Sections属性数组中对象的内容不正确.
根据您发布的代码,您只需从NSFetchedResultsController中检索NSManagedObject实例.也许对于那是什么感到困惑?
在代码中,我正在NSManagedObject从中检索实例NSFetchedResultsController,以便显示每个表格单元格的书名和作者名称(何时cellForRowAtIndexPath被调用).但是,每个部分的标题UITableView不是从NSManagedObject我的理解中获取的,而是取自_NSDefaultSectionInfo实现NSFetchedResultsSectionInfo协议的对象(何时titleForHeaderInSection被调用).
我通过以下为调试编写的代码实现了这一点:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id mySection = [[fetchedBooks sections] objectAtIndex:section];
NSLog(@"%@", mySection)
return [[[self.fetchedResultsController sections] objectAtIndex:section] name];
}
Run Code Online (Sandbox Code Playgroud)
日志的结果是<_NSDefaultSectionInfo:0x8462b90>.Sections属性的NSFetchedResultsController文档显示:
/* Returns an array of objects that implement the NSFetchedResultsSectionInfo protocol.
It's expected that developers use the returned array when implementing the following methods of the UITableViewDataSource protocol
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
*/
Run Code Online (Sandbox Code Playgroud)
如果我错了,请纠正我:_NSDefaultSectionInfo不是NSManagedObject吗?如果是这样,当作者被更改时,如何NSFetchedResultsController检测_NSDefaultSectionInfo对象NSManagedObject的更改?
所以这导致了几个问题:
你如何在另一个视图中更改作者的姓名?
更改作者姓名的代码如上所示saveAuthorName.App中的流程如下:
从主菜单中UITableView,选择使用导航控制器打开新书籍视图的书本单元格.
从书籍视图中,选择使用导航控制器打开新的选择 - 作者视图的选择作者.(所有作者都列在a中UITableView)
从"选择 - 作者"视图中,选择使用导航控制器打开新编辑 - 作者视图的任何作者.
在编辑 - 作者视图中更改作者姓名并保存,其中关闭视图并将先前视图(选择 - 作者)带入导航控制器堆栈中.
现在可以选择不同的作者并对其进行编辑等等.直到关闭此视图.(带来书籍视图)
关闭书籍视图,显示所有书籍的主视图.
单元格中的作者姓名是旧的还是只是部分标题?
Cell完全更新了作者姓名(感谢willChangeValueForKey和didChangeValueForKey调用saveAuthorName).只有节标题是旧的.
你的委托方法是什么样的?
你能详细说明哪一个吗?我在上面的代码部分编写了与我相关的所有委托方法.这包括:
cellForRowAtIndexPath
titleForHeaderInSection
controllerDidChangeContent
还需要其他方法吗?
从编辑返回后,您确定 - [UITableViewDatasource tableView:titleForHeaderInSection:]是否正在触发?
100%肯定.titleForHeaderInSection带来旧值,并在保存更改后调用它.(cellForRowAtIndexPath在保存更改但是带来新值后也会调用)
什么NSFetchedResultsControllerDelegate方法在返回时触发?
如果您的意思是在saveAuthorName调用以下方法后保存(意味着,在调用之后):
controllerWillChangeContent: (不使用它,仅用于调试信息)
controller:didChangeObject: (不使用它,仅用于调试信息)
controllerDidChangeContent:
如果您的意思是在调用以下方法后返回主视图(意味着关闭Book视图):
cellForRowAtIndexPath
titleForHeaderInSection
numberOfSectionsInTableView
numberOfRowsInSection
我感谢您的帮助.谢谢!
你在实现-controller:didChangeSection:atIndex:forChangeType:?
是的,但是在更改作者姓名时不会被解雇.目前的配置NSFetchedResultsController如下:
更改书名(而不是作者姓名)将didChangeSection在NSFetchedResultsController配置如下时触发事件:
这意味着委托被正确地连接到NSFetchedResultsController.
它看起来像调用,[book willChangeValueForKey:@"author"]并且[book didChangeValueForKey:@"author"]在更改作者姓名时不足以NSFetchedResultsController监视部分更改.
一般来说,你不应该需要保存更改,如果你正在处理一个单一的NSManagedObjectContext同时为NSFetchedResultsController和UIViewController所做出的变化.
如果您有多个,则不适用NSManagedObjectContext.
假设你有一个NSManagedObjectContext,我会确保你设置了委托,NSFetchedResultsController并在委托方法中放置断点,看看你是否得到任何回调.
我还将使用调试器并打印出您正在使用的NSManagedObject的指针,并确保它们是相同的.如果他们不是那么它将指向一个问题NSManagedObjectContext.
嗯,还是有点模糊.你说的数段是不正确的?
根据您发布的代码,您只需NSManagedObject从中检索实例NSFetchedResultsController.也许对于那是什么感到困惑?
的NSFetchedResultsController是仅具有一个或多个部分的容器.这些部分也只是一个容纳一个或多个NSManagedObject实例的容器.这些是您可以访问应用程序中任何其他位置的相同实例NSManagedObject(假设单个NSManagedObjectContext设计).
因此,如果您更改应用程序中NSManagedObject 任何位置的数据,它将在更新中更新,NSFetchedResultsController因为它是同一个对象,而不是副本,而是完全相同的对象.
所以这导致了几个问题:
-[UITableViewDatasource tableView: titleForHeaderInSection:]从编辑返回后,您确定自己正在解雇吗?NSFetchedResultsControllerDelegate方法在返回时开火?你在实施-controller: didChangeSection: atIndex: forChangeType:吗?如果没有,请这样做并告诉我它是否会发生火灾.如果它发射,它什么时候开火?在致电之前或之后-[UITableViewDatasource tableView: titleForHeaderInSection:]?
这开始听起来像苹果虫.
几点想法:
| 归档时间: |
|
| 查看次数: |
10511 次 |
| 最近记录: |