В моей реализации Базовых данных есть ошибка, которую я не могу охватить, и мне нужно несколько советов о том, где я должен искать, чтобы выяснить, как ее исправить.
Короче говоря, у меня есть UITableView
, заполненный NSFetchedResultsController
. Я хочу, чтобы мои пользователи могли изменять параметры сортировки данных, поэтому я предоставляю им средство выбора, которое изменит базовый fetchedResultsController
на другие предустановленные конфигурации. Я могу переключаться между различными fetchedResultsControllers
без каких-либо проблем. Я могу добавлять и удалять данные, никогда не происходит сбоев, никаких проблем. Однако в 2 (из 6 и всегда одинаковых 2) конфигурациях fetchedResultController
элементы, добавленные в базу данных, не добавляются в представление таблицы. И элементы, которые находятся в виде таблицы, исчезают после редактирования.
Вот шаги, которые я прошёл, чтобы воспроизвести ошибку:
- Установить сортировку для конфигурации, которая работает
- Добавить новый элемент в базу данных (в этот момент
controllerWillChangeContent
срабатывает)
- Изменить конфигурацию, которая не работает
- Добавить новый элемент в базу данных (
controllerWillChangeContent
не срабатывает)
- Переключиться обратно в рабочую конфигурацию
- Добавленный предмет теперь виден в
tableView
- Переключиться обратно на нерабочую конфигурацию
- Предмет теперь виден в
tableView
- Редактировать элемент (
controllerWillChangeContent
запускается, но controller:DidChangeObject:
запускается с типом NSFetchedResultsChangeDelete
вместо NSFetchedResultsChangeUpdate
)
- Вернитесь к рабочей конфигурации, и элемент будет изменен и снова виден.
Я в своем уме с этой штукой. У меня совершенно нет идей. Буквально нет разницы между тем, как эти 2 fetchedResultsControllers
созданы и 4 другими. Любая помощь, которая может быть предложена, будет очень оценена.
- EDIT -
По-прежнему возникают некоторые проблемы с этим. Чтобы повторить некоторые ответы на вопросы TechZen:
- Ни один из моих атрибутов не установлен в качестве переходных значений
- Я сейчас использую плоскую модель. Это единое целое с прямыми атрибутами. Там нет никаких отношений.
- Проблема сохраняется с кэшем, установленным на
nil
- Я устанавливаю старый делегат
frc
на nil
перед каждым изменением и устанавливаю нового делегата frc
на self
в конце коммутатора. Это верно для всех 6 frc
с
- Я выпускаю старую
frc
и создаю новую каждый раз, когда пользователь переключается на другую опцию сортировки.
Для тех, кто заинтересован, код, который я использую для переключения frc
, находится в сущности здесь
- РЕДАКТИРОВАТЬ 2 -
Создание награды для любого, кто может указать мне правильное направление.
- Редактировать 3 -
По запросу, вот код для моих методов делегата:
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
-(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;
}
}
-(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:
if (!self.searchIsActive) {
[self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
} else {
[self.searchDisplayController.searchResultsTableView reloadData];
}
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
И информация получила мою модель данных:
// Person.h
#import <CoreData/CoreData.h>
@interface Person : NSManagedObject
{
}
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * company;
@property (nonatomic, retain) NSString * comments;
@property (nonatomic, retain) NSString * job;
@property (nonatomic, retain) NSDate * logDate;
@property (nonatomic, retain) NSString * location;
@property (nonatomic, retain) NSNumber * rating;
@property (nonatomic, retain) NSString * imagePath;
@property (nonatomic, retain) NSString * thumbPath;
@end
// Person.m
#import "Person.h"
@implementation Person
@dynamic name;
@dynamic company;
@dynamic comments;
@dynamic job;
@dynamic logDate;
@dynamic location;
@dynamic rating;
@dynamic imagePath;
@dynamic thumbPath;
@end
Информация о модели данных:
Entity: Person
Property: comments
kind: attribute
type: string
optional: YES
Property: name
kind: attribute
type: string
optional: NO
Property: rating
kind: attribute
kind: Int 16
optional: YES
min value: 0
max value: 5
Property: job
kind: attribute
kind: string
optional: YES
Property: company
kind: attribute
kind: string
optional: YES
Property: location
kind: attribute
kind: string
optional: YES
Property: imagePath
kind: attribute
kind: string
optional: YES
Property: thumbPath
kind: attribute
kind: string
optional: YES
Property: logDate
kind: attribute
kind: date
optional: YES
Ничего особенного в этом нет.