В моем приложении Lion у меня есть эта модель данных:
Отношения subitems
внутри Item
упорядочены .
Xcode 4.1 (сборка 4B110) создал для меня файл Item.h
, Item.m
, SubItem.h
и SubItem.h
.
Вот содержание (автоматически) Item.h
:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class SubItem;
@interface Item : NSManagedObject {
@private
}
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSOrderedSet *subitems;
@end
@interface Item (CoreDataGeneratedAccessors)
- (void)insertObject:(SubItem *)value inSubitemsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromSubitemsAtIndex:(NSUInteger)idx;
- (void)insertSubitems:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeSubitemsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInSubitemsAtIndex:(NSUInteger)idx withObject:(SubItem *)value;
- (void)replaceSubitemsAtIndexes:(NSIndexSet *)indexes withSubitems:(NSArray *)values;
- (void)addSubitemsObject:(SubItem *)value;
- (void)removeSubitemsObject:(SubItem *)value;
- (void)addSubitems:(NSOrderedSet *)values;
- (void)removeSubitems:(NSOrderedSet *)values;
@end
И вот содержание (автоматически) Item.m
:
#import "Item.h"
#import "SubItem.h"
@implementation Item
@dynamic name;
@dynamic subitems;
@end
Как видите, класс Item
предлагает метод с именем addSubitemsObject:
. К сожалению, при попытке использовать его таким образом:
Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";
SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];
[item addSubitemsObject:subItem];
эта ошибка появляется:
2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet
Вы можете помочь мне?
Обновить:
Спустя всего 1787 дней после моего отчета об ошибках, сегодня (1 августа 2016 года) Apple написала мне следующее: «Пожалуйста, проверьте эту проблему с последней бета-версией iOS 10 и обновите свой отчет об ошибке на bugreport.apple.com со своими результатами». , Будем надеяться, что сейчас самое время :)
mutableOrderedSetValueForKey:
)Ответы:
Я воспроизвел ваши настройки как с вашей моделью данных, так и с моей собственной, с разными именами. Я получил ту же ошибку в обоих случаях.
Похоже, ошибка в автоматически сгенерированном коде Apple.
источник
Я согласен, что здесь может быть ошибка. Я изменил реализацию установщика объекта добавления, чтобы правильно добавить к NSMutableOrderedSet.
Переназначение набора для self.subitems обеспечит отправку уведомлений Will / DidChangeValue.
источник
Я решил улучшить решение, внедрив все необходимые методы:
источник
willChangeValueForKey:withSetMutation:usingObjects
, чего вы успешно избежали. После этого просто используйте[[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values]
или[[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values]
по необходимости. Смотрите мой ответ для деталей.Да, это определенно ошибка Базовых данных. Некоторое время назад я написал исправление на основе ObjC-Runtime, но в то время я думал, что оно будет исправлено в ближайшее время. В любом случае, не повезло, поэтому я разместил его на GitHub как KCOrderedAccessorFix . Обойти проблему на всех ваших сущностях:
Одна сущность в частности:
Или только для одного отношения:
источник
- (BOOL)kc_needsOrderedSetAccessorFix;
или что-то, что проверяет версию Foundation / iOS.objc_msg_send
)Вместо того чтобы делать копию, я предлагаю использовать аксессор в NSObject, чтобы получить доступ к NSMutableOrderedSet отношений.
например, примечания к выпуску Core Data для iOS v5.0 ссылаются на это.
В коротком тесте это сработало в моем приложении.
источник
NSStringFromSelector(@selector(subitems))
хотя :)Я отследил ошибку. Это происходит в
willChangeValueForKey:withSetMutation:usingObjects:
.Этот вызов вызывает цепочку уведомлений, которые могут быть трудно отследить, и, конечно, изменения в одном респонденте могут иметь последствия для другого, что, как я подозреваю, объясняет, почему Apple ничего не сделала.
Тем не менее, это нормально в Set, и это только операции Set на OrderedSet, которые работают со сбоями. Это означает, что есть только четыре метода, которые необходимо изменить. Поэтому все, что я сделал, это преобразовал операции Set в их эквивалентные операции Array. Они работают отлично и минимальные (но необходимые) накладные расходы.
На критическом уровне это решение страдает одним критическим недостатком; если вы добавляете объекты, и один из объектов уже существует, то он либо не добавляется, либо перемещается в конец упорядоченного списка (я не знаю, какой). В любом случае ожидаемый упорядоченный индекс объекта к тому времени, когда мы
didChange
достигаем, отличается от ожидаемого. Это может сломать приложения некоторых людей, но это не влияет на мои, так как я только добавляю новые объекты или подтверждаю их окончательное местоположение перед тем, как добавить их.Конечно, есть более простое решение. это выглядит следующим образом;
источник
Документ Apple To Many Relations говорит: вы должны получить доступ к изменяемому набору прокси или упорядоченному набору, используя
Изменение этого набора добавит или удалит отношения к вашему управляемому объекту. Доступ к изменяемому упорядоченному набору с помощью метода доступа с помощью [] или. запись неверна и потерпит неудачу.
источник
Получил ту же ошибку, у меня сработало решение @LeeIII (спасибо!). Я предлагаю немного изменить это:
Содержание
Item+category.m
:источник
Если вы используете mogenerator, то вместо
просто используйте:
источник
mogenerator
но у меня все еще есть ошибка.Лично я только что заменил вызовы сгенерированных методов CoreData на прямые вызовы метода, как описано в другом решении @Stephan:
Это устраняет необходимость в категориях, которые могут позже вступить в конфликт с решением Apple для сгенерированного кода, когда ошибка будет исправлена.
Это имеет дополнительный плюс того, чтобы быть официальным способом сделать это!
источник
addObject:
называется дважды?Кажется, что если вы связываете родителя с потомком, устанавливая родителя для потомка, а не наоборот, это работает без сбоев.
Так что если вы делаете:
вместо
Это должно работать, по крайней мере, это работает на iOS 7 и не было никаких проблем с отношениями.
источник
У меня была такая же проблема, но только когда я попробовал что-то отличное от того, что я делал. Я не вижу код для подэлемента, но я предполагаю, что он имеет обратную ссылку на элемент. Давайте назовем эту почитаемую ссылку «parentItem», тогда самое простое решение:
Эффект состоит в том, что он использует собственный код яблока, и это просто и чисто. Кроме того, набор автоматически добавляется, а все наблюдатели обновляются. Нет проблем.
источник
Я просто заболел этой проблемой и решил ее, используя гораздо более простую реализацию, чем другие, описанные здесь. Я просто использую доступные методы
NSManagedObject
для работы с отношениями, когда не использую подклассы.Пример реализации для вставки сущности в
NSOrderedSet
отношение будет выглядеть следующим образом:Это прекрасно работает, и это то, что я использовал, прежде чем перейти к
NSManagedObject
подклассам.источник
Эта проблема возникла у меня при переносе проекта с Objective-C на Swift 2 с XCode 7 . Этот проект работал, и по уважительной причине: я использовал MOGenerator, у которого были методы замены, чтобы исправить эту ошибку. Но не все методы требуют замены.
Итак, вот полное решение с примером класса, максимально полагаясь на средства доступа по умолчанию.
Допустим, у нас есть список с заказанными товарами
Сначала быстрый выигрыш, если у вас отношения один-ко-многим, проще всего сделать следующее:
вместо
Теперь, если это не вариант , вот что вы можете сделать:
Конечно, если вы используете Objective-C, вы можете сделать то же самое, потому что именно здесь я и получил идею :)
источник
Leelll, вы уверены, что после такой пользовательской настройки значения NSMutableOrderedSet, хранящиеся в этом наборе, будут корректно сохранены в базе данных CoreData? Я не проверял это, но похоже, что CoreData ничего не знает о NSOrderedSet и ожидает, что NSSet будет контейнером связи со многими.
источник
Я думаю, что всем не хватает настоящей проблемы. Дело не в методах доступа, а в том, что
NSOrderedSet
это не подклассNSSet
. Так что, когда-interSectsSet:
вызывается с упорядоченным набором в качестве аргумента, это терпит неудачу.не удается с
*** -[NSSet intersectsSet:]: set argument is not an NSSet
Похоже, исправление заключается в изменении реализации операторов множеств, чтобы они прозрачно обрабатывали типы. Нет причин, почему
-intersectsSet:
должен работать с упорядоченным или неупорядоченным множеством.Исключение происходит в уведомлении об изменении. Предположительно в коде, который обрабатывает обратные отношения. Так как это происходит только тогда, когда я устанавливаю обратную связь.
Следующее помогло мне
источник
Я только что получил проблему в Swift (Xcode 6.1.1).
Ответ был: НЕ КОДИРУЙТЕ ЛЮБОГО МЕТОДА ИЛИ ДОПОЛНИТЕЛЬНЫХ в ваших подклассах NSManagedObject. Я думаю, что это ошибка компилятора. Очень странная ошибка
Надеюсь, поможет ..
источник
Я решил эту проблему, установив обратное значение «Нет обратного», я не знаю почему, возможно, есть Apple Bug.
источник
У меня такая же ситуация с элементом под названием «сигналы» вместо «подпункты». Решение с tempset работает в моем тестировании. Кроме того, у меня была проблема с методом removeSignals :. Это переопределение, кажется, работает:
Если есть лучший способ сделать это, пожалуйста, дайте мне знать. Мои входные данные никогда не превышают 10 -20 пунктов, поэтому производительность не так важна - тем не менее, пожалуйста, укажите на что-нибудь важное.
Спасибо,
Damien
источник
Я нашел этот вопрос, прибегая к поиску сообщения об ошибке, и просто хотел указать, что столкнулся с этой ошибкой немного по-другому (не используя упорядоченные наборы). Это не совсем ответ на заданный вопрос, но я выкладываю его здесь только на тот случай, если он пригодится всем, кто сталкивается с этим вопросом во время поиска.
Я добавил новую версию модели, добавил некоторые отношения к существующим моделям и сам определил методы add * Object в заголовочном файле. Когда я попытался позвонить им, я получил ошибку выше.
Просмотрев мои модели, я понял, что тупо забыл поставить галочку напротив «Отношения со многими».
Поэтому, если вы сталкиваетесь с этим и не используете упорядоченные наборы, дважды проверьте свою модель.
источник
Я нашел исправление для этой ошибки, которая работает для меня. Я просто заменяю это:
с этим:
источник
Лучшая версия правильного ответа в SWIFT
источник
Я обнаружил, что использование метода ЛиIII сработало, но при профилировании оказалось, что он был чрезвычайно медленным. Для разбора 1000 элементов потребовалось 15 секунд. Комментирование кода для добавления отношения превратило 15 секунд в 2 секунды.
Мой обходной путь (который быстрее, но гораздо уродливее) включает создание временного изменяемого массива, а затем копирование в упорядоченный набор, когда весь анализ выполнен. (это только выигрыш в производительности, если вы собираетесь добавить много отношений).
Я надеюсь, что это поможет кому-то еще!
источник
Роберт,
Я согласен, что ваш ответ будет работать для этого, но имейте в виду, что есть автоматически созданный метод для добавления целого набора значений в отношения. Документация Apple ( как показано здесь в разделе «Отношения ко многим» или здесь в разделе «Пользовательские методы доступа к многим отношениям») реализует их следующим образом:
Вы можете легко скомпилировать ваш набор отношений вне основных данных, а затем добавить их все сразу, используя этот метод. Это может быть менее уродливо, чем метод, который вы предложили;)
источник
Я уверен, что это наконец исправлено в iOS 10 beta 6 !
источник