Nano Hash - криптовалюты, майнинг, программирование

CoreData: сортировка элементов по индексу в наборе категорий

У меня есть простая функциональность диспетчера каталогов с элементами в категориях, ЗА ИСКЛЮЧЕНИЕМ одного элемента может быть в нескольких категориях.

Элемент имеет ключ 'parents', который является NSSet родительских категорий.

Категория имеет ключ 'items', который является NSOrderedSet его подэлементов.

Я использую NSFetchedResultController и его делегата для заполнения моей таблицы элементами

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(ANY parents == %@)", self.category];

[fetchRequest setFetchBatchSize:30];
[fetchRequest setSortDescriptors:@[????????];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

Итак, используя этот код, я могу получить список элементов в self.category.

В моем пользовательском интерфейсе у меня есть Drag and Drop функциональность. Так что я могу перемещать элементы внутри категорий.

Мой вопрос: как Category1, так и Category2 содержат ссылки на одни и те же элементы Item1 и Item2. Мне нужно, чтобы Item1, Item2 заказывал в Category1 и Item2, Item1 в Category2. Вот почему я сделал свойство category.items как NSOrderedSet.

Но я просто не могу сортировать предметы по их индексу в category.items

Я пытался использовать блоки в дескрипторах сортировки - не сработало, я пытался использовать селекторы в дескрипторах сортировки - не работало, я пытался создавать подклассы дескрипторов сортировки - как-то работает, но не обновляет элементы, когда я меняю их индекс. category.items.
Вот так в моем NSSortDescriptorSubclass:

- (NSComparisonResult)compareObject:(Item*)object1 toObject:(Item*)object2 {

int index1 = [self.category.items indexOfObject:object1];
int index2 = [self.category.items indexOfObject:object2];

if (index1 > index2) {
    return NSOrderedDescending;
} else if (index1 < index2) {
    return NSOrderedAscending;
}

return NSOrderedSame;

} But items order won't be updated in my UI if I change order in Category.items

Поэтому, пожалуйста, помогите мне отсортировать элементы по их индексу в наборе category.items. Может быть, есть способ сделать это с помощью каких-то ключей, операторов, выражений, чего-то еще. Спасибо.

02.04.2013

  • И вы настаиваете на использовании NSFetchedResultsController? Так как у вас уже есть self.category. Доступ к элементам в этом упорядоченном наборе в порядке их индекса прост, как вызов -objectAtIndex: в вашем методе источника данных. 02.04.2013
  • Да, я хотел бы использовать его, потому что я хочу, чтобы мои элементы автоматически обновлялись, когда я изменяю некоторые свойства из других частей приложения. 02.04.2013
  • Хорошо. Дескриптор сортировки с блоком сравнения определенно подойдет для одноразовой сортировки. Сложность заключается в том, чтобы NSFetchedResultsController знал об изменении порядка отношений. Я не знаю, как это можно сделать. 02.04.2013
  • К сожалению, вы не можете использовать блоки для дескрипторов сортировки в CoreData. Просто выдает ошибку. 02.04.2013

Ответы:


1

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

Вместо этого вам нужно ввести свой собственный атрибут для сортировки. У вас может быть сущность categoryItem, имеющая однозначное отношение как к Category, так и к Item, а также к атрибуту sequence.

В вашем FRC вы выбираете объект categoryItem, а при отображении вы просто используете categoryItem.item для доступа к свойствам элемента. Когда вы меняете порядок (например, с помощью перетаскивания), вы должны перенумеровать все categoryItem и назначить правильный порядковый номер.

-- РЕДАКТИРОВАТЬ --

Чтобы пометить categoryItem как "грязный" при изменении какой-либо детали элемента: вы можете реализовать метод markDirty в categoryItem, который выглядит следующим образом:

// CategoryItem.m
-(void)markDirty {
    [self willChangeValueForKey:@"sequence"];
    [self didChangeValueForKey:@"sequence"];
}

// EditItemController.m
item.attribute = newAttribute; 
for (CategoryItem *i in item.categoryItems) { [i markDirty]; }
02.04.2013
  • это может сработать! большое спасибо! позвольте мне попытаться реализовать это и отметить ваш ответ как правильный. Спасибо 02.04.2013
  • знаете ли вы обходной путь проблемы, которую создает ваше решение: теперь, если я изменяю некоторые параметры в элементе, мое табличное представление не обновляется (оно будет обновляться только при изменении параметра categoryItem) 02.04.2013
  • Да, тонкий вопрос. Вы можете попробовать обходной путь в моем отредактированном ответе. Вы пробовали простой [tableView reloadData]; или, возможно, также [self.frc performFetch:self.frc.fetchRequest error:nil];? 02.04.2013
  • Кстати, я решил реализовать ваше решение markDirty, потому что оно обновляет только одну строку в моем табличном представлении, а не все, и пока у меня есть изображения с URL-адресов, определенно было бы лучше обновить только одну запись. еще раз спасибо! 03.04.2013

  • 2

    Отношения «один ко многим» в Core Data — это NSSets, а не NSOrderedSets. По этой причине индекс элемента в категории не сохраняется. Вы можете добавить еще одну сущность в свою модель Core Data под названием, что-то вроде IndexValue. IndexValue будет иметь два атрибута, categoryId или categoryName (в зависимости от того, что имеет смысл), а затем categoryIndex. Item тогда будет иметь отношение один ко многим с этим объектом (и обратное отношение один к одному, поскольку нет необходимости повторно использовать эти объекты, они должны быть уникальными). Для каждого Category, в котором находится Item, будет создан IndexValue.

    РЕДАКТИРОВАТЬ: кажется, что упорядоченное свойство было добавлено для поддержки NSOrderedSet отношений один ко многим в OS X 10.7 и iOS 5. Это должно быть то, на что вы ориентируетесь и используете. Документация по этой функции скудна, но порядок должен сохраняться без необходимости использовать NSSortDescriptors при выборке отношения. Что касается изменения порядка, я не уверен, как это поддерживается. Производительность на больших наборах данных ниже при использовании этого метода по сравнению с описанным выше методом.

    02.04.2013
  • Это не совсем верно. Упорядоченные отношения доступны с iOS5. Вы можете преобразовать обычную связь (на основе NSSet) в упорядоченную связь (на основе NSOrderedSet), установив упорядоченный флаг в свойстве отношения в вашей модели данных. 02.04.2013
  • Да, это правда, они добавили этот упорядоченный флажок, поэтому я хотел бы использовать его 02.04.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..