Ошибка основных данных: как правильно загрузить набор объектов для отношений объектов - PullRequest
0 голосов
/ 18 ноября 2011

Например:

У меня есть две сущности с именами Project и Todo, где у проекта есть много задач (отношение ко многим), и у каждой задачи есть один проект (см. Изображение).

CoreData setup of entities

В моем ViewController.h у меня есть что-то вроде:

...
NSArray *projectArray;
NSArray *todosArray;

@property (nonatomic,retain) NSArray *projectArray;
@property (nonatomic,retain) NSArray *todosArray;
...

В моем ViewController.m у меня есть что-то вроде:

...
@synthesize projectArray,todosArray;
...
self.projectArray = [self fetchRequestForAllProjects];
...

У пользователя есть интерфейс, где он может выбирать между всеми различными проектами.Как только пользователь выбирает проект, должны быть установлены соответствующие объекты todo для загрузки и представления.

Вопрос 1: Как загрузить набор задач вtodosArray лучшим образом?

Я делал это так (также в ViewController.m):

...
// after deselecting a project entry I reset the todosArray
self.todosArray = nil;
...
//when the user selects a new project I reset the todosArray like this:
self.todosArray = [selectedProject.todos allObjects];
...

Но каким-то образом приложение очень редко вылетаетпоследняя строка кода.Есть ли проблемы с моим кодом?

Вопрос 2 : Было бы лучше использовать другой запрос на выборку для объектов todos?

ОБНОВЛЕНИЕ:

Я использую todosArray в различных методах ViewController.m:

(а) для получения количества объектов, (б) представления каждой записи задач в строке табличного представления и(c) для идентификации выбранной записи todo (выбор строки броска)

Ответы [ 2 ]

2 голосов
/ 18 ноября 2011

Ответ № 1

Лучше всего сортировать их, когда вы вытаскиваете все из набора в массив. Это обеспечит согласованность вашего пользовательского опыта:

NSSet *projectTodoEntities = [mySelectedProject valueForKey:@"todos"];
NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"myKey" ascending:YES];
NSArray *sortedToDos = [projectTodoEntities sortedArrayUsingDescriptors:[NSArray arrayWithObject:sorter]];

Ответ № 2

Нет, получение дорого по сравнению с простым доступом к отношениям. Выборка ударит по диску и т. Д.

0 голосов
/ 19 февраля 2014

Для ответа № 1. 1). Пожалуйста, убедитесь, что selectedProject удален в другом потоке, если он будет удален, данные ядра пометят этот NSManagedObject как недействительный, при попытке доступа к свойству этого объекта будет выдано исключение NSObjectInaccessibleException. 2). Все NSManagedObject ассоциируются с NSManagedObjectContext, контекст ограничен определенным потоком или очередью потока, когда вы обращаетесь к отношению «todos», пока оно находится в состоянии ошибки, оно инициирует выборку из постоянного хранилища, вы должны убедиться, что поток выполнения действителен для NSManagedObjectContext В противном случае вы должны использовать приведенный ниже код.

NSManagedObjectContext *context = [selectedProject managedObjectContext];
__weak YouControllerClass *weakSelf;
[context performBlockAndWait:^{
    weakSelf.todosArray = [selectedProject.todos allObjects];
}];

Ответ # 2: было бы лучше использовать другой запрос на выборку для объектов todos?

По умолчанию отношение «задачи» возвращается как состояние ошибки, когда вы получаете доступ к свойству проекта «todos:», оно фактически вызывает выборку из постоянного хранилища в первый раз, данные ядра могут кэшировать эти объекты «задачи» позже в памяти, поэтому вы получите быстрый доступ в будущем (если вы не сбросите NSManagedObjectContext)

Для большинства сценариев, например, когда пользователь проверяет свои списки ограниченных задач, вполне нормально инициировать другой запрос на выборку, производительность не является реальной проблемой, если в объекте todo отсутствуют огромные данные большого двоичного объекта. Для критических сценариев производительности, таких как использование базовых данных для сохранения сотен фотографий и метаданных в качестве взаимосвязи, когда вы рисуете все эти фотографии в UIView на основе высоты, ширины или свойства URL-адреса объекта фотографии, вы должны предусмотреть предварительную выборку метаданных фотографии, чтобы избежать снижение производительности (операция io).

...