ฉันรู้ว่าอาจมีวิธีแก้ปัญหาที่ง่ายมากสำหรับเรื่องนี้ ฉันใช้ตัวอย่าง apple iphoneCoreDataRecipes ฉันกำลังพยายามเจาะลึกจากตารางเริ่มต้น (RecipeTypeTableViewController) ของ RecipeTypes (เช่น เครื่องดื่ม, ของหวาน, Entree) ไปยังมุมมองตารางถัดไปพร้อมรายการสูตรอาหารประเภทเหล่านั้น (RecipeListTableViewController) ฉันสร้างคลาส RecipeType ใหม่ โดยคิดว่าฉันสามารถใช้คลาสนี้เพื่อส่งคืนสูตรอาหารของ RecipeType ที่เลือกได้ จนถึงตอนนี้สิ่งที่ดีที่สุดที่ฉันทำได้คืออนุญาตให้เลือกได้ แต่มันแสดงรายการสูตรอาหารทั้งหมดเหมือนกัน โค้ดต้นฉบับเริ่มต้นด้วย RecipeListTableViewController โดยใช้ NSFetchedResults เพื่อแสดงสูตรอาหารทั้งหมด ตอนนี้ฉันมีมุมมองเริ่มต้นของ RecipeTypes แล้ว แต่ฉันไม่แน่ใจว่าจะส่งประเภทที่เลือกไปยัง RecipeListTableViewController ได้อย่างไร ฉันต้องเปลี่ยน RecipeListTableViewController เพื่อแสดงรายการ RecipeType ที่เลือก แต่ฉันไม่แน่ใจว่าจะนำไปใช้อย่างไร ฉันคิดว่าโดยพื้นฐานแล้วฉันต้องการส่ง NSMutableArray ของ fetchedresults ไปยัง tableview อื่น แต่ไม่แน่ใจว่าควรใช้ทิศทางใด และฉันไม่ต้องการทำให้การทำงานอื่นๆ ใน RecipeListTableViewController ยุ่งเหยิง เช่น การค้นหาและแก้ไขสูตรอาหาร นี่คือรูปภาพการทำงานของตารางจนถึงตอนนี้ [RecipeTypeTableView][1] และ [RecipeListTableview][2] ขอขอบคุณล่วงหน้าสำหรับข้อเสนอแนะใด ๆ
ลบสิ่งเหล่านี้แล้ว
ไฟล์: RecipeType.h
ไฟล์: RecipeType.m
ฉันใช้ NSManagedObject *type จากคลาสสูตรอาหารของฉัน NSManagedObject เพื่อสร้างมุมมองเริ่มต้นของประเภทสูตรอาหาร (อาหารเรียกน้ำย่อย Bev ฯลฯ) บน RecipeTypeTableViewController -
ไฟล์: Recipe.h
@interface Recipe : NSManagedObject
@property (nonatomic, strong) NSManagedObject *type;
ไฟล์: RecipeTypeTableViewController.h
// RecipeTypeTableViewController.h
// Recipes
#import <UIKit/UIKit.h>
@interface RecipeTypeTableViewController : UITableViewController <NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSManagedObject *type;
@end
ไฟล์: RecipeTypeTableViewController.m - การเตรียมการสำหรับส่วนที่ทำต่อ
#import "RecipeTypeTableViewController.h"
#import "Recipe.h"
#import "RecipeListTableViewController.h"
@interface RecipeTypeTableViewController () <NSFetchedResultsControllerDelegate>
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@end
@implementation RecipeTypeTableViewController
static NSString *MyIdentifier = @"showRecipes";
- (void)viewDidLoad {
[super viewDidLoad];
// register this class for our cell to this table view under the specified identifier 'ARecipeType'
self.title = @"Category";
//[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"ARecipeType"];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangePreferredContentSize:)name:UIContentSizeCategoryDidChangeNotification object:nil];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
//abort();
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.title = @"Category";
}
- (void)didChangePreferredContentSize:(NSNotification *)notification
{
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];
}
#pragma mark - Table view data source
//- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//#warning Incomplete implementation, return the number of sections
//return [[self.recipeTypeFetchedResultsController sections] count];
// return 1;
//}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Number of rows is the number of recipe types
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
//return self.recipeTypes.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ARecipeType" forIndexPath:indexPath];
// Configure the cell
NSManagedObject *recipeType = [self.recipeTypes objectAtIndex:indexPath.row];
cell.textLabel.text = [recipeType valueForKey:@"name"];
return cell;
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
// Set up the fetched results controller if needed.
if (_fetchedResultsController == nil) {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"RecipeType" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSLog(@"Setting up a Fetched Results Controller for the Entity named %@", entity);
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Recipe"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
return _fetchedResultsController;
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"showRecipes"]) {
NSLog(@"Setting RecipeType for the RecipeListTableViewController");
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Recipe *selectedType = [self.fetchedResultsController objectAtIndexPath:indexPath];
RecipeListTableViewController *recipeListViewController = segue.destinationViewController;
recipeListViewController.type = selectedType;
recipeListViewController.managedObjectContext = self.managedObjectContext;
}
}
ไฟล์: RecipeListTableViewController.h - ส่วน NSPredicate และแคช FRC
#import <UIKit/UIKit.h>
#import "RecipeAddViewController.h"
@interface RecipeListTableViewController : UITableViewController <RecipeAddDelegate, NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSManagedObject *type;
ไฟล์: RecipeListTableViewController.m
#import "RecipeListTableViewController.h"
#import "RecipeDetailViewController.h"
#import "Recipe.h"
#import "RecipeTableViewCell.h"
#import "Recipe+Extensions.h"
#import "TypeSelectionViewController.h"
#import "IngredientDetailViewController.h"
#import "Ingredient.h"
#import "WhereViewController.h"
#import "FavoriteListTableViewController.h"
#import "RecipeTypeTableViewController.h"
#import "RecipeType.h"
@interface RecipeListTableViewController () <NSFetchedResultsControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating>
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSArray *filteredList;
@property (nonatomic, strong) NSFetchRequest *searchFetchRequest;
@property (nonatomic, strong) UISearchController *searchController;
typedef NS_ENUM(NSInteger, RecipesSearchScope)
{
searchScopeRecipe = 0,
searchScopeIngredients = 1
};
@end
@implementation RecipeListTableViewController
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
// Set up the fetched results controller if needed.
if (_fetchedResultsController == nil) {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[NSFetchedResultsController deleteCacheWithName:@"Recipe"];
// Create predicate
//if (self.type) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == %@", self.type];
[fetchRequest setPredicate:predicate];
//}
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Recipe"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
return _fetchedResultsController;
}
/
เมื่อฉันตั้งค่าแคช FRC เป็น "สูตรอาหาร" มันขัดข้อง มันแสดงให้เห็นเบาะแสนี้เพื่อดูแคช CoreData: ข้อผิดพลาด FATAL: แคชถาวรของข้อมูลส่วนไม่ตรงกับการกำหนดค่าปัจจุบัน คุณได้กลายพันธุ์คำขอดึงข้อมูลของ NSFetchedResultsController ภาคแสดง หรือคำอธิบายการเรียงลำดับของ NSFetchedResultsController อย่างผิดกฎหมาย
หากฉันตั้งค่าแคชเป็นศูนย์ หรือเพิ่ม [NSFetchedResultsController DeleteCacheWithName:@"Recipe"]; ก่อนเซตภาคแสดง สิ่งต่างๆ ทำงานตามที่คาดไว้ ฉันมีแคชนี้ในตัวควบคุมมุมมองเริ่มต้นและตัวควบคุมมุมมองที่สอง นั่นอาจเป็นปัญหา - ฉันต้องการแคชในตัวควบคุมมุมมองเริ่มต้นเท่านั้น