Wyjątek wrzucony do accesorów wygenerowanych przez nsorderedset

W mojej aplikacji Lion mam taki model danych:

Tutaj wpisz opis obrazka

Relacja subitems wewnątrz Item jest uporządkowany .

Xcode 4.1 (build 4B110) stworzył dla mnie Plik Item.h, Item.m, SubItem.h i SubItem.h.

Oto treść (autogeneraowana) 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

A oto treść (autogenerowana) Item.m:

#import "Item.h"
#import "SubItem.h"

@implementation Item

@dynamic name;
@dynamic subitems;

@end

Jak widać, Klasa Item oferuje metodę o nazwie addSubitemsObject:. Niestety, próbując użyć go w tym sposób:

Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";

SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];

[item addSubitemsObject:subItem];

Pojawia się ten błąd:

2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet
Możesz mi pomóc?

Update:

Po zaledwie 1787 dniach od mojego zgłoszenia, dzisiaj (1 sierpnia 2016) Apple napisał do mnie tak: " proszę zweryfikować ten problem z najnowszą wersją beta iOS 10 i zaktualizować raport o błędzie na bugreport.apple.com z Twoimi wynikami.". Miejmy nadzieję, że to odpowiedni moment:)

Author: Dev, 2011-09-12

25 answers

Odtworzyłem Twoją konfigurację zarówno z Twoim modelem danych, jak i jednym z moich o różnych nazwach. Mam ten sam błąd w obu przypadkach.

Wygląda na błąd w autogenerowanym kodzie Apple ' a.

 261
Author: TechZen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-13 00:24:17

Zgadzam się, że może tu być błąd. Zmodyfikowałem implementację add object setter, aby poprawnie dopisać do NSMutableOrderedSet.

- (void)addSubitemsObject:(SubItem *)value {
    NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
    [tempSet addObject:value];
    self.subitems = tempSet;
}
/ Align = "left" / subitems zapewni, że powiadomienia Will/DidChangeValue zostaną wysłane.
 243
Author: JLust,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-29 18:21:31

Postanowiłem ulepszyć rozwiązanie poprzez wdrożenie wszystkich wymaganych metod:

static NSString *const kItemsKey = @"<#property#>";

- (void)insertObject:(<#Type#> *)value in<#Property#>AtIndex:(NSUInteger)idx {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet insertObject:value atIndex:idx];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)removeObjectFrom<#Property#>AtIndex:(NSUInteger)idx {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet removeObjectAtIndex:idx];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)insert<#Property#>:(NSArray *)values atIndexes:(NSIndexSet *)indexes {
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet insertObjects:values atIndexes:indexes];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)remove<#Property#>AtIndexes:(NSIndexSet *)indexes {
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet removeObjectsAtIndexes:indexes];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)replaceObjectIn<#Property#>AtIndex:(NSUInteger)idx withObject:(<#Type#> *)value {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet replaceObjectAtIndex:idx withObject:value];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)replace<#Property#>AtIndexes:(NSIndexSet *)indexes with<#Property#>:(NSArray *)values {
    [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet replaceObjectsAtIndexes:indexes withObjects:values];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)add<#Property#>Object:(<#Type#> *)value {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSUInteger idx = [tmpOrderedSet count];
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    [tmpOrderedSet addObject:value];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)remove<#Property#>Object:(<#Type#> *)value {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSUInteger idx = [tmpOrderedSet indexOfObject:value];
    if (idx != NSNotFound) {
        NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
        [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet removeObject:value];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

- (void)add<#Property#>:(NSOrderedSet *)values {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    NSUInteger valuesCount = [values count];
    NSUInteger objectsCount = [tmpOrderedSet count];
    for (NSUInteger i = 0; i < valuesCount; ++i) {
        [indexes addIndex:(objectsCount + i)];
    }
    if (valuesCount > 0) {
        [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet addObjectsFromArray:[values array]];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

- (void)remove<#Property#>:(NSOrderedSet *)values {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    for (id value in values) {
        NSUInteger idx = [tmpOrderedSet indexOfObject:value];
        if (idx != NSNotFound) {
            [indexes addIndex:idx];
        }
    }
    if ([indexes count] > 0) {
        [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet removeObjectsAtIndexes:indexes];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    }
}
 110
Author: Dmitry Makarenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 06:56:26

Tak, to jest na pewno główny błąd danych. Jakiś czas temu napisałem poprawkę opartą na ObjC-Runtime, ale w tym czasie pomyślałem, że wkrótce zostanie naprawiona. W każdym razie, nie ma takiego szczęścia, więc zamieściłem go na Githubie jako KCOrderedAccessorFix . Obejść problem na wszystkich swoich podmiotach:

[managedObjectModel kc_generateOrderedSetAccessors];

Jeden podmiot w szczególności:

[managedObjectModel kc_generateOrderedSetAccessorsForEntity:entity];

Lub tylko dla jednego związku:

[managedObjectModel kc_generateOrderedSetAccessorsForRelationship:relationship];
 38
Author: Sterling Archer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-22 07:05:55

Zamiast zrobić kopię proponuję użyć accessor w NSObject, aby uzyskać dostęp do nsmutableorderedset relacji.

- (void)addSubitemsObject:(SubItem *)value {
      NSMutableOrderedSet* tempSet = [self mutableOrderedSetValueForKey:@"subitems"];
      [tempSet addObject:value];
 }
Na przykład uwagi do wydania danych podstawowych dla systemu iOS v5.0 odnoszą się do tego. W krótkim teście zadziałało w mojej aplikacji.
 32
Author: Stephan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-26 07:18:08

Namierzyłem pluskwę. Występuje w willChangeValueForKey:withSetMutation:usingObjects:.

To wywołanie uruchamia łańcuch powiadomień, które mogą być trudne do wyśledzenia, i oczywiście zmiany w jednym responder mogą mieć wpływ na inny, co podejrzewam, że dlatego Apple nic nie zrobił.

Jest jednak w porządku w zestawie i jego tylko operacje Set na zamówionym zestawie, że awaria. Oznacza to, że są tylko cztery metody, które muszą zostać zmienione. Dlatego wszystko, co zrobiłem, to konwersja operacji zestawu na ich równoważne operacje tablicowe. Działają one doskonale i minimalne (ale konieczne) koszty ogólne.

Na poziomie krytycznym, To rozwiązanie cierpi na jedną krytyczną wadę; jeśli dodajesz obiekty, a jeden z obiektów już istnieje, to albo nie jest dodawany lub przenoszony na tył listy uporządkowanej (Nie wiem, która). W obu przypadkach oczekiwany uporządkowany indeks obiektu do czasu przybycia didChange różni się od oczekiwanego. Może to złamać aplikacje niektórych ludzi, ale to nie wpływa na moje, ponieważ dodaję tylko nowe obiekty lub potwierdzam ich ostateczne lokalizacje przed dodaniem.

- (void)addChildrenObject:(BAFinancialItem *)value {
    if ([self.children containsObject:value]) {
        return;
    }
    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:self.children.count];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] addObject:value];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
}

- (void)removeChildrenObject:(BAFinancialItem *)value {
    if (![self.children containsObject:value]) {
        return;
    }
    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:[self.children indexOfObject:value]];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] removeObject:value];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
}

- (void)addChildren:(NSOrderedSet *)values {
    if ([values isSubsetOfOrderedSet:self.children]) {
        return;
    }
    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.children.count, values.count)];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
}

- (void)removeChildren:(NSOrderedSet *)values {
    if (![self.children intersectsOrderedSet:values]) {
        return;
    }
    NSIndexSet * indexSet = [self.children indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [values containsObject:obj];
    }];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
}
Oczywiście, jest łatwiejsze rozwiązanie. jest ona następująca;
- (void)addChildrenObject:(BAFinancialItem *)value {
    if ([self.children containsObject:value]) {
        return;
    }
    [self insertObject:value inChildrenAtIndex:self.children.count];
}

- (void)removeChildrenObject:(BAFinancialItem *)value {
    if (![self.children containsObject:value]) {
        return;
    }
    [self removeObjectFromChildrenAtIndex:[self.children indexOfObject:value]];
}

- (void)addChildren:(NSOrderedSet *)values {
    if ([values isSubsetOfOrderedSet:self.children]) {
        return;
    }
    [self insertChildren:values atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.children.count, values.count)]];
}

- (void)removeChildren:(NSOrderedSet *)values {
    if (![self.children intersectsOrderedSet:values]) {
        return;
    }
    [self removeChildrenAtIndexes:[self.children indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [values containsObject:obj];
    }]];
}
 17
Author: Owen Godfrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-29 00:22:54

The Apple docs To Many Relations mówi: powinieneś uzyskać dostęp do Proxy mutable set lub ordered set używając

NSMutableOrderedSet * set = [managedObject mutableOrderedSetValueForKey:@"toManyRelation"];

Modyfikacja tego zestawu spowoduje dodanie lub usunięcie relacji do zarządzanego obiektu. Dostęp do mutable ordered set za pomocą accesora, czy to z [], czy . notacja jest błędna i zawiedzie.

 10
Author: Nicolas Manzini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-31 13:42:01

Otrzymałem ten sam błąd, @LeeIII rozwiązanie działało dla mnie (dzięki!). Proponuję nieco zmodyfikować:

  • użyj kategorii objective-c do przechowywania nowej metody (więc nie stracimy naszej metody, jeśli element zostanie wygenerowany ponownie)
  • sprawdź czy mamy już zmienny zestaw

Zawartość Item+category.m:

#import "Item+category.h"

@implementation Item (category)

- (void)addSubitemsObject:(SubItem *)value {
    if ([self.subitems isKindOfClass:[NSMutableOrderedSet class]]) {
        [(NSMutableOrderedSet *)self.subitems addObject:value];
    } else {
        NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
        [tempSet addObject:value];
        self.subitems = tempSet;
    }
}

@end
 9
Author: Danik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-03 17:51:48

Jeśli używasz mogenerator, to zamiast

[parentObject add<Child>sObject:childObject];

Po prostu użyj:

[[parent object <child>sSet] addObject:childObject];
 8
Author: Καrτhικ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-10 18:43:58

Osobiście właśnie zamieniłem wywołania do metod generowanych przez CoreData na wywołania bezpośrednie do metody opisanej w innym rozwiązaniu przez @ Stephan:

NSMutableOrderedSet* tempSet = [self mutableOrderedSetValueForKey:@"subitems"];
      [tempSet addObject:value];
[tempSet addObject:value];

Usuwa to potrzebę kategorii, które mogą później kolidować z rozwiązaniem firmy Apple do wygenerowanego kodu, gdy błąd zostanie naprawiony.

To ma dodatkowy plus bycia oficjalnym sposobem, aby to zrobić!

 7
Author: Grouchal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-04 09:05:55

Wydaje się, że jeśli połączysz rodzica z dzieckiem, ustawiając rodzica na dziecko, a nie na odwrót, to działa bez awarii.

Więc jeśli to zrobisz:

[child setParent:parent]

Zamiast

[parent setChildObects:child]

Powinno działać, przynajmniej działa na iOS 7 i nie miał żadnych problemów z relacją.

 5
Author: Cata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-01 21:03:51

Miałem ten sam problem, ale tylko wtedy, gdy próbowałem czegoś innego niż to, co robiłem. Nie widzę kodu dla subitu, ale zakładam, że ma link odwrotny do elementu. Let 's call this reveres link, "parentItem", then the easiest solution is this:

Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";

SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];

//[item addSubitemsObject:subItem];
subItem.parentItem = item;

Efekt jest taki, że wykorzystuje własny kod apple i jest prosty i czysty. Ponadto zestaw jest automatycznie dodawany, a wszystkie obserwatory są aktualizowane. Nie ma sprawy.

 3
Author: Owen Godfrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-15 04:54:31

Po prostu wpadłem w ten problem i rozwiązałem go za pomocą znacznie prostszej implementacji niż inne opisane tutaj. Po prostu korzystam z metod dostępnych na NSManagedObject do radzenia sobie z relacjami, gdy nie używam podklas.

Przykładowa implementacja wstawiania encji do relacji NSOrderedSet wyglądałaby następująco:

- (void)addAddress:(Address *)address
{
    if ([self.addresses containsObject:address]) {
        return;
    }
    // Use NSManagedObject's methods for inserting an object
    [[self mutableOrderedSetValueForKey:@"addresses"] addObject:address];
}

To działa idealnie i jest to, czego używałem, zanim przeniosłem się do NSManagedObject podklas.

 3
Author: Mic Pringle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-16 10:38:30

Ten problem pojawił się podczas migracji projektu z Objective-C do Swift 2 z XCode 7 . Ten projekt kiedyś działał i nie bez powodu: używałem MOGenerator, który miał metody zastępcze, aby naprawić ten błąd. Ale nie wszystkie metody wymagają wymiany.

Oto kompletne rozwiązanie z klasą przykładową, opierającą się w jak największym stopniu na domyślnych accesorach.

Załóżmy, że mamy listę z uporządkowanymi przedmiotami

Pierwsza a Szybka Wygrana jeśli masz związek jeden do wielu, najłatwiej jest po prostu zrobić:

item.list = list

Zamiast

list.addItemsObject(item)

Teraz, jeśli to nie jest opcja , Oto co możesz zrobić:

// Extension created from your DataModel by selecting it and
// clicking on "Editor > Create NSManagedObject subclass…"

extension List {
  @NSManaged var items: NSOrderedSet?
}

class List

  // Those two methods work out of the box for free, relying on
  // Core Data's KVC accessors, you just have to declare them
  // See release note 17583057 https://developer.apple.com/library/prerelease/tvos/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc7_release_notes.html
  @NSManaged func removeItemsObject(item: Item)
  @NSManaged func removeItems(items: NSOrderedSet)

  // The following two methods usually work too, but not for NSOrderedSet
  // @NSManaged func addItemsObject(item: Item)
  // @NSManaged func addItems(items: NSOrderedSet)

  // So we'll replace them with theses

  // A mutable computed property
  var itemsSet: NSMutableOrderedSet {
    willAccessValueForKey("items")
    let result = mutableOrderedSetValueForKey("items")
    didAccessValueForKey("items")
    return result
  }

  func addItemsObject(value: Item) {
    itemsSet.addObject(value)
  }

  func addItems(value: NSOrderedSet) {
    itemsSet.unionOrderedSet(value)
  }
end

Oczywiście, jeśli używasz Objective-C, możesz zrobić dokładnie to samo, ponieważ to tutaj wpadłem na pomysł:)

 3
Author: Nycen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-11 12:53:08
Zgadzam się, że może tu być jakiś błąd. Zmodyfikowałem implementację add object >setter, aby poprawnie dołączyć do zestawu NSMutableOrderedSet.
- (void)addSubitemsObject:(SubItem *)value {
     NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
     [tempSet addObject:value];
     self.subitems = tempSet;
}
/ Align = "left" / subitems zapewni, że Will/DidChangeValue powiadomienia >są wysyłane.

Leelll, czy jesteś pewien, że po takiej niestandardowej konfiguracji nsmutableorderedset wartości zapisane w tym zestawie zostaną poprawnie zapisane w bazie danych przez CoreData? Nie sprawdzałem tego, ale wygląda jak CoreData nie wie nic o NSOrderedSet i oczekuje nsset jako kontenera relacji-many.

 3
Author: DisableR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-20 08:53:36

Myślę, że każdemu brakuje prawdziwego problemu. Nie jest to w metodach accessora, ale raczej w fakcie, że NSOrderedSet nie jest podklasą NSSet. Więc gdy -interSectsSet: jest wywołane z uporządkowanym zestawem jako argumentem, to się nie powiedzie.

NSOrderedSet* setA = [NSOrderedSet orderedSetWithObjects:@"A",@"B",@"C",nil];
NSSet* setB = [NSSet setWithObjects:@"C",@"D", nil];

 [setB intersectsSet:setA];

*** -[NSSet intersectsSet:]: set argument is not an NSSet

Wygląda na to, że poprawką jest zmiana implementacji operatorów zestawu tak, aby obsługiwali typy w sposób przejrzysty. Nie ma powodu, dla którego {[6] } powinien działać z uporządkowanym lub nieuporządkowanym zestawem.

Wyjątek występuje w zmianie powiadomienie. Prawdopodobnie w kodzie, który obsługuje odwrotną relację. Ponieważ dzieje się tak tylko wtedy, gdy ustawiam odwrotną relację.

Poniższy trik zrobił dla mnie

@implementation MF_NSOrderedSetFixes

+ (void) fixSetMethods
{
    NSArray* classes = [NSArray arrayWithObjects:@"NSSet", @"NSMutableSet", @"NSOrderedSet", @"NSMutableOrderedSet",nil];

    [classes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString* name = obj;
        Class aClass = objc_lookUpClass([name UTF8String]);
        [MF_NSOrderedSetFixes fixMethodWithSetArgument:@selector(intersectsSet:) forClass:aClass];
        [MF_NSOrderedSetFixes fixMethodWithSetArgument:@selector(isSubsetOfSet:) forClass:aClass];
    }];
}

typedef BOOL (*BoolNSetIMP)(id _s,SEL sel, NSSet*);

/*
    Works for all methods of type - (BOOL) method:(NSSet*) aSet
*/
+ (void) fixMethodWithSetArgument:(SEL) aSel forClass:(Class) aClass 
{
    /* Check that class actually implements method first */
    /* can't use get_classInstanceMethod() since it checks superclass */
    unsigned int count,i;
    Method method = NULL;
    Method* methods = class_copyMethodList(aClass, &count);
    if(methods) {
        for(i=0;i<count;i++) {
            if(method_getName(methods[i])==aSel) {
                method = methods[i];
            }
        }
        free(methods);
    }
    if(!method) {
        return;
    }

   // Get old implementation
   BoolNSetIMP originalImp  = (BoolNSetIMP) method_getImplementation(method);
   IMP newImp = imp_implementationWithBlock(^BOOL(NSSet *_s, NSSet *otherSet) {
        if([otherSet isKindOfClass:[NSOrderedSet class]]) {
            otherSet = [(NSOrderedSet*)otherSet set];
        }
        // Call original implementation
        return originalImp(_s,aSel,otherSet);
    });
    method_setImplementation(method, newImp);
}
@end
 2
Author: Entropy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-22 18:13:49

Właśnie mam problem w Swift (Xcode 6.1.1).

Odpowiedź brzmiała nie koduj żadnych metod ani dodatkowych rzeczy w podklasach NSManagedObject. Myślę, że to błąd kompilatora. Bardzo dziwny robak ..

Mam nadzieję, że to pomoże ..

 2
Author: lobodart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-05 01:35:47

Rozwiązałem ten problem ustawiając inverse Na No Inverse, Nie wiem dlaczego, może jest błąd Apple.Tutaj wpisz opis obrazka

 2
Author: LevinYan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-20 01:31:24

Mam taką samą sytuację z elementem o nazwie "signals" zamiast "subitems". Rozwiązanie z tempset działa w moich testach. Ponadto miałem problem z metodą removeSignals:. To nadpisanie wydaje się działać:

- (void)removeSignals:(NSOrderedSet *)values {
    NSMutableOrderedSet* tempset = [NSMutableOrderedSet orderedSetWithOrderedSet:self.signals];
    for (Signal* aSignal in values) {
        [tempset removeObject:aSignal];
    }
    self.signals = tempset;
}
Jeśli jest na to lepszy sposób, proszę dać mi znać. Moje wartości wejściowe nigdy nie są większe niż 10 -20 pozycji, więc wydajność nie jest zbyt dużym problemem - niemniej proszę zwrócić uwagę na cokolwiek istotnego.

Dzięki,

Damien

 1
Author: Damien Del Russo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-09 17:37:58

Znalazłem to pytanie googlując komunikat o błędzie i chciałem tylko zaznaczyć, że napotkałem ten błąd w nieco inny sposób (nie używając uporządkowanych zestawów). Nie jest to do końca odpowiedź na dane pytanie, ale zamieszczam go tutaj na wypadek, gdyby był pomocny dla każdego, kto natknie się na to pytanie podczas wyszukiwania.

Dodałem nową wersję modelu, dodałem kilka relacji do istniejących modeli i sam zdefiniowałem metody Add * Object w pliku nagłówkowym. Kiedy próbowałem do nich zadzwonić, dostałem błąd powyżej.

Po przejrzeniu moich modeli, zdałem sobie sprawę, że głupio zapomniałem zaznaczyć pole wyboru "dla wielu relacji".

Więc jeśli napotkasz to i nie używasz zamówionych zestawów, sprawdź ponownie swój model.

 1
Author: BenV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-23 22:38:27

Znalazłem poprawkę dla tego błędu, który działa dla mnie. Zamieniam to:

[item addSubitemsObject:subItem];

Z tym:

item.subitemsObject = subItem;
 1
Author: Bimawa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-05 01:52:03

Odkryłem, że metoda LeeIII zadziałała, ale na profilowaniu okazało się, że jest drastycznie powolna. Przeanalizowanie 1000 pozycji zajęło 15 sekund. Komentowanie kodu dodającego relację zamieniło 15 sekund na 2 sekundy.

Moje obejście (które jest szybsze, ale o wiele bardziej brzydkie) polega na stworzeniu tymczasowej tablicy mutowalnej, a następnie skopiowaniu do uporządkowanego zestawu, gdy Wszystkie zostanie wykonane parsowanie. (jest to tylko zwycięstwo wydajności, jeśli masz zamiar dodać wiele relacje).

@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;
    }
}
Mam nadzieję, że to pomoże komuś innemu!
 0
Author: Robert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-30 09:23:53

Robert,

Zgadzam się, że Twoja odpowiedź zadziała na to, ale pamiętaj, że istnieje automatycznie utworzona metoda dodawania całego zestawu wartości do relacji. Dokumentacja Apple (Jak widać tutaj w sekcji "to-many Relationships" lub tutaj w sekcji "Custom to-Many relationships Accessor Methods") implementuje je w ten sposób:

- (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];
}

Możesz łatwo skompilować swój zestaw relacji poza podstawowymi danymi, a następnie dodać je wszystkie od razu za pomocą tej metody. Może być mniej brzydki niż metoda, którą zasugerowałeś;)

 0
Author: JiuJitsuCoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-13 03:39:34

W końcu udało się to naprawić w iOS 10 beta 6 !

 0
Author: an0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-15 19:48:32

Lepsza wersja poprawnej odpowiedzi w języku SWIFT

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

tempSet.add(newItem)
parent!.subItems = tempSet
 0
Author: emreoktem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-14 10:40:20