在高级应用中集成NSFetchedResultsController到MyStash应用
立即解锁
发布时间: 2025-08-26 00:37:11 阅读量: 4 订阅数: 11 


iOS核心数据高级编程指南
### 在高级应用中集成 NSFetchedResultsController 到 MyStash 应用
在开发 MyStash 应用时,我们希望实现笔记和密码的显示、添加、编辑和删除功能。本文将详细介绍如何使用 `NSFetchedResultsController` 来实现这些功能。
#### 1. 创建获取结果控制器
为了在 MyStash 应用中显示笔记和密码,我们需要创建获取结果控制器。具体步骤如下:
- **声明控制器和上下文**:在 `NoteListViewController.h` 和 `PasswordListViewController.h` 中声明获取结果控制器和托管对象上下文,并声明这两个控制器实现 `NSFetchedResultsControllerDelegate` 协议。
```objc
// NoteListViewController.h
#import <UIKit/UIKit.h>
@interface NoteListViewController : UITableViewController<NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@end
```
```objc
// PasswordListViewController.h
#import <UIKit/UIKit.h>
@interface PasswordListViewController : UITableViewController<NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@end
```
- **初始化控制器实例**:在 `NoteListViewController.m` 和 `PasswordListViewController.m` 中初始化获取结果控制器实例。
```objc
// NoteListViewController.m
@synthesize fetchedResultsController;
@synthesize managedObjectContext;
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController != nil)
{
return fetchedResultsController;
}
// 创建实体的获取请求
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// 设置批量大小
[fetchRequest setFetchBatchSize:20];
// 按笔记标题升序排序
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// 创建获取结果控制器
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Note"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
// 获取结果到获取结果控制器中
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return fetchedResultsController;
}
```
对于 `PasswordListViewController.m`,需要将实体名称和缓存名称从 `Note` 改为 `System`,并将排序描述符使用的属性从 `title` 改为 `name`。
- **实现协议方法**:在 `NoteListViewController.m` 和 `PasswordListViewController.m` 中实现 `NSFetchedResultsControllerDelegate` 协议方法。
```objc
// NoteListViewController.m 和 PasswordListViewController.m
#pragma mark -
#pragma mark Fetched results controller delegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
```
#### 2. 将获取结果控制器集成到表格中
接下来,需要将 `UITableViewController` 的调用委托给 `FetchedResultsController`。在 `NoteListViewController.m` 和 `PasswordListViewController.m` 中编辑以下方法:
```objc
// NoteListViewController.m 和 PasswordListViewController.m
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"NoteCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
```
对于 `PasswordListViewController.m`,将 `CellIdentifier` 的值改为 `PasswordCell`。
#### 3. 实现配置单元格方法
为每个控制器实现 `configureCell:` 方法。
- **NoteListViewController.m**
```objc
@interface NoteListViewController()
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
```
0
0
复制全文
相关推荐










