Исключение, генерируемое в сгенерированных средствах доступа NSOrderedSet - PullRequest
363 голосов
/ 12 сентября 2011

В моем приложении Lion у меня есть эта модель данных:

enter image description here

Отношение subitems внутри Item упорядочено .

Xcode 4.1 (build 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 с вашими результатами. ". Будем надеяться, что сейчас самое подходящее время:)

Ответы [ 25 ]

1 голос
/ 09 февраля 2012

У меня такая же ситуация с элементом под названием «сигналы» вместо «подпункты».Решение с tempset работает в моем тестировании.Кроме того, у меня была проблема с методом removeSignals :.Это переопределение работает:

- (void)removeSignals:(NSOrderedSet *)values {
    NSMutableOrderedSet* tempset = [NSMutableOrderedSet orderedSetWithOrderedSet:self.signals];
    for (Signal* aSignal in values) {
        [tempset removeObject:aSignal];
    }
    self.signals = tempset;
}

Если есть лучший способ сделать это, пожалуйста, дайте мне знать.Мои входные значения никогда не превышают 10 -20 пунктов, поэтому производительность не так важна - тем не менее, пожалуйста, укажите на что-нибудь важное.

Спасибо,

Дэмиен

0 голосов
/ 14 января 2018

Лучшая версия правильного ответа в SWIFT

var tempSet = NSMutableOrderedSet()
if parent!.subItems != nil {
    tempSet = NSMutableOrderedSet(orderedSet: parent!.subItems!)
}

tempSet.add(newItem)
parent!.subItems = tempSet
0 голосов
/ 30 апреля 2012

Я обнаружил, что использование метода ЛиIII сработало, но при профилировании обнаружил, что он был чрезвычайно медленным.Для разбора 1000 элементов потребовалось 15 секунд.Комментирование кода для добавления отношения превратило 15 секунд в 2 секунды.

Мой обходной путь (который быстрее, но гораздо более уродлив) включает создание временного изменяемого массива, а затем копирование в упорядоченный набор, когда all синтаксический анализ завершен.(это только выигрыш в производительности, если вы собираетесь добавить много отношений).

@property (nonatomic, retain) NSMutableArray* tempItems;
 ....
@synthesize tempItems = _tempItems;
 ....

- (void) addItemsObject:(KDItem *)value 
{
    if (!_tempItems) {
        self.tempItems = [NSMutableArray arrayWithCapacity:500];
    }
    [_tempItems addObject:value];
}

// Call this when you have added all the relationships
- (void) commitRelationships 
{
    if (_tempItems) {
        self.items = [NSOrderedSet orderedSetWithArray:self.tempItems];
        self.tempItems = nil;
    }
}

Я надеюсь, что это поможет кому-то еще!

0 голосов
/ 15 августа 2016

Я совершенно уверен, что наконец-то исправлено в iOS 10 beta 6 !

0 голосов
/ 13 мая 2012

Роберт,

Я согласен, что ваш ответ сработает для этого, но имейте в виду, что есть автоматически созданный метод для добавления целого набора значений в отношение.Документация Apple ( как показано здесь в разделе «Отношения ко многим» или здесь в разделе «Пользовательские методы доступа к множеству отношений») реализует их следующим образом:

- (void)addEmployees:(NSSet *)value
{
[self willChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueUnionSetMutation
      usingObjects:value];
[[self primitiveEmployees] unionSet:value];
[self didChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueUnionSetMutation
      usingObjects:value];
}

- (void)removeEmployees:(NSSet *)value
{
[self willChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueMinusSetMutation
      usingObjects:value];
[[self primitiveEmployees] minusSet:value];
[self didChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueMinusSetMutation
      usingObjects:value];
}

Вы можете легко скомпилировать набор отношений вне базовых данных, а затем добавить их все сразу, используя этот метод.Это может быть менее безобразно , чем метод, который вы предложили;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...