W mojej aplikacji Lion mam ten model danych:
Relacja subitems
wewnątrz Item
jest uporządkowana .
Xcode 4.1 (build 4B110) stworzył dla mnie plik Item.h
, Item.m
, SubItem.h
i SubItem.h
.
Oto treść (automatycznie generowana) 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ść (automatycznie generowana) 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 ten 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?
Aktualizacja:
Po zaledwie 1787 dniach od zgłoszenia błędu dzisiaj (1 sierpnia 2016 r.) Apple napisał do mnie: „Sprawdź ten problem za pomocą najnowszej wersji beta systemu iOS 10 i zaktualizuj swój raport o błędach na stronie bugreport.apple.com z wynikami”. . Miejmy nadzieję, że to właściwy czas :)
mutableOrderedSetValueForKey:
)Odpowiedzi:
Odtworzyłem twoją konfigurację zarówno z twoim modelem danych, jak i jednym z moich własnych o różnych nazwach. W obu przypadkach dostałem ten sam błąd.
Wygląda na błąd w automatycznie generowanym kodzie Apple.
źródło
Zgadzam się, że może tu być błąd. Zmodyfikowałem implementację narzędzia do ustawiania obiektów dodawania, aby poprawnie dołączała się do NSMutableOrdersSet.
Ponowne przypisanie zestawu do self.subitems zapewni wysłanie powiadomień Will / DidChangeValue.
źródło
Zdecydowałem się ulepszyć rozwiązanie, wdrażając wszystkie wymagane metody:
źródło
willChangeValueForKey:withSetMutation:usingObjects
, czego udało ci się uniknąć. Następnie użyj[[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values]
lub[[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values]
odpowiednio. Zobacz moją odpowiedź, aby poznać szczegóły.Tak, to zdecydowanie błąd Core Data. Jakiś czas temu napisałem poprawkę opartą na środowisku wykonawczym ObjC, ale w tym czasie pomyślałem, że wkrótce zostanie naprawiona. W każdym razie, nie ma takiego szczęścia, więc opublikowałem to na GitHub jako KCOragedAccessorFix . Obejmij problem we wszystkich swoich podmiotach:
W szczególności jeden podmiot:
Lub tylko dla jednego związku:
źródło
- (BOOL)kc_needsOrderedSetAccessorFix;
coś, co sprawdza wersję Foundation / iOS.objc_msg_send
)Zamiast zrobić kopię, sugeruję użyć akcesorium w NSObject, aby uzyskać dostęp do NSMutableOrdersSet relacji.
np. Informacje o wydaniu Core Data dla iOS 5.0 odnoszą się do tego.
W krótkim teście zadziałało w mojej aplikacji.
źródło
NSStringFromSelector(@selector(subitems))
:)Śledziłem błąd. Występuje w
willChangeValueForKey:withSetMutation:usingObjects:
.To wywołanie uruchamia łańcuch powiadomień, które mogą być trudne do śledzenia, i oczywiście zmiany w jednym z respondentów mogą mieć wpływ na inny, co podejrzewam, że Apple nic nie zrobił.
Jednak w Set jest w porządku, a to tylko operacje Set na zestawie OrdersSet, które działają nieprawidłowo. Oznacza to, że są tylko cztery metody, które należy zmienić. Dlatego wszystko, co zrobiłem, to przekonwertowanie operacji Set na ich równoważne operacje Array. Działają one idealnie i minimalne (ale konieczne) koszty ogólne.
Na poziomie krytycznym to rozwiązanie ma jedną wadę krytyczną; jeśli dodajesz obiekty, a jeden z nich już istnieje, to nie jest on dodawany ani przenoszony na koniec listy uporządkowanej (nie wiem, która). W obu przypadkach oczekiwany uporządkowany indeks obiektu w chwili dotarcia do nas
didChange
różni się od oczekiwanego. Może to zepsuć aplikacje niektórych osób, ale nie wpływa to na moje, ponieważ zawsze dodam nowe obiekty lub potwierdzam ich ostateczne położenie przed ich dodaniem.Oczywiście istnieje łatwiejsze rozwiązanie. wygląda to następująco;
źródło
Dokument Apple To Many Relations mówi: powinieneś uzyskać dostęp do zestawu mutable proxy lub zestawu uporządkowanego za pomocą
Modyfikacja tego zestawu spowoduje dodanie lub usunięcie relacji do zarządzanego obiektu. Dostęp do mutable uporządkowanego zestawu za pomocą akcesorium czy za pomocą [] lub. notacja jest błędna i zawiedzie.
źródło
Otrzymałem ten sam błąd, rozwiązanie @LeeIII zadziałało dla mnie (dzięki!). Sugeruję nieznaczną modyfikację:
Treść
Item+category.m
:źródło
Jeśli używasz mogeneratora, to zamiast
po prostu użyj:
źródło
mogenerator
ale nadal mam błąd.Osobiście właśnie zastąpiłem wywołania metod wygenerowanych przez CoreData bezpośrednimi wywołaniami metody opisanymi w innym rozwiązaniu przez @Stephan:
Eliminuje to potrzebę kategorii, które mogą później kolidować z rozwiązaniem Apple wygenerowanego kodu, gdy błąd zostanie naprawiony.
Ma to tę dodatkową zaletę, że jest to oficjalny sposób!
źródło
addObject:
dzwonimy dwa razy?Wydaje się, że jeśli połączysz rodzica z dzieckiem, ustawiając go, a nie na odwrót, działa to bez awarii.
Więc jeśli to zrobisz:
zamiast
Powinien działać, przynajmniej działa na iOS 7 i nie miał żadnych problemów z relacją.
źródło
Miałem ten sam problem, ale tylko wtedy, gdy próbowałem czegoś innego niż to, co robiłem. Nie widzę kodu dla podelementu, ale założę, że ma on link zwrotny do elementu. Nazwijmy to odsłonięciem linku „parentItem”, wtedy najłatwiejszym rozwiązaniem jest:
Skutkuje to tym, że wykorzystuje własny kod Apple i jest prosty i czysty. Ponadto zestaw jest dodawany automatycznie, a wszyscy obserwatorzy są aktualizowani. Nie ma problemu.
źródło
Właśnie zepsułem ten problem i rozwiązałem go, stosując znacznie prostszą implementację niż inne opisane tutaj. Po prostu korzystam z metod dostępnych na
NSManagedObject
radzenia sobie z relacjami, gdy nie używam podklas.Przykładowa implementacja wstawiania encji do
NSOrderedSet
relacji wyglądałaby następująco:Działa to doskonale i tego właśnie używałem przed przejściem do
NSManagedObject
podklas.źródło
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: korzystałem z MOGeneratora, który miał metody zastępcze, aby naprawić ten błąd. Ale nie wszystkie metody wymagają wymiany.
Oto kompletne rozwiązanie z przykładową klasą, w miarę możliwości oparte na domyślnych akcesoriach.
Załóżmy, że mamy listę z zamówionymi przedmiotami
Najpierw szybka wygrana, jeśli masz relację jeden do wielu, najłatwiej jest po prostu zrobić:
zamiast
Teraz, jeśli nie jest to opcja , oto co można zrobić:
Oczywiście, jeśli używasz Objective-C, możesz zrobić dokładnie to samo, ponieważ to tutaj wpadłem na pomysł :)
źródło
Leelll, czy jesteś pewien, że po takiej niestandardowej konfiguracji wartości NSMutableOrdersSet zapisanych w tym zestawie zostaną poprawnie zapisane w bazie danych przez CoreData? Nie sprawdziłem tego, ale wygląda na to, że CoreData nic nie wie o NSOrdersSet i oczekuje, że NSSet będzie kontenerem wielu relacji.
źródło
Myślę, że wszystkim brakuje prawdziwego problemu. Nie dotyczy to metod akcesora, ale raczej faktu, że
NSOrderedSet
nie jest to podklasaNSSet
. Więc gdy-interSectsSet:
zostanie wywołany z uporządkowanym zestawem jako argumentem, zawiedzie.nie działa z
*** -[NSSet intersectsSet:]: set argument is not an NSSet
Wygląda na to, że poprawka polega na zmianie implementacji operatorów zbioru, aby obsługiwali typy w sposób przejrzysty. Bez powodu, dla którego:
-intersectsSet:
powinien pracować z zestawem uporządkowanym lub nieuporządkowanym.Wyjątek występuje w powiadomieniu o zmianie. Przypuszczalnie w kodzie, który obsługuje odwrotną relację. Ponieważ dzieje się tak tylko wtedy, gdy ustawię odwrotną relację.
Poniższe zrobiły dla mnie lewę
źródło
Właśnie dostałem problem w Swift (Xcode 6.1.1).
Odpowiedź brzmiała: NIE KODUJ ŻADNEJ METODY ANI DODATKOWYCH RZECZY w podklasach NSManagedObject. Myślę, że to błąd kompilatora. Bardzo dziwny błąd ..
Mam nadzieję, że to pomoże ..
źródło
Rozwiązałem ten problem, ustawiając odwrotność na No Inverse, nie wiem dlaczego, może jest błąd Apple.
źródło
Mam taką samą sytuację z elementem o nazwie „sygnały” zamiast „podelementy”. Rozwiązanie z tempsetem działa w moich testach. Ponadto miałem problem z metodą removeSignals:. To zastąpienie wydaje się działać:
Jeśli istnieje lepszy sposób, prosimy o kontakt. Moje wartości wejściowe nigdy nie są większe niż 10-20 pozycji, więc wydajność nie stanowi większego problemu - niemniej prosimy o wskazanie czegoś istotnego.
Dzięki,
Damien
źródło
Znalazłem to pytanie, przeglądając komunikat o błędzie, i chciałem tylko zauważyć, że napotkałem ten błąd w nieco inny sposób (nie używając uporządkowanych zestawów). To nie jest całkiem odpowiedź na dane pytanie, ale zamieszczam je tutaj, na wypadek, gdyby było pomocne dla każdego, kto natknie się na to pytanie podczas wyszukiwania.
Dodałem nową wersję modelu, dodałem pewne relacje do istniejących modeli i sam zdefiniowałem metody add * Object w pliku nagłówkowym. Kiedy próbowałem do nich zadzwonić, otrzymałem błąd powyżej.
Po przejrzeniu moich modeli zdałem sobie sprawę, że głupio zapomniałem zaznaczyć pole wyboru „Relacja z wieloma osobami”.
Jeśli więc napotykasz na to i nie używasz uporządkowanych zestawów, sprawdź dokładnie swój model.
źródło
Znalazłem naprawę tego błędu, który działa dla mnie. Właśnie zastępuję to:
z tym:
źródło
Lepsza wersja poprawnej odpowiedzi w SWIFT
źródło
Odkryłem, że metoda LeeIII zadziałała, ale przy profilowaniu okazało się, że była drastycznie powolna. Parsowanie 1000 elementów zajęło 15 sekund. Komentowanie kodu w celu dodania relacji zamieniło 15 sekund w 2 sekundy.
Moje obejście (który jest szybszy, ale o wiele bardziej brzydki) wymaga utworzenia tymczasowego zmienny tablicę następnie kopiując do uporządkowanego zbioru, gdy wszystko parsowanie jest wykonywana. (jest to tylko wygrana wydajności, jeśli zamierzasz dodać wiele relacji).
Mam nadzieję, że pomoże to komuś innemu!
źródło
Robert,
Zgadzam się, że twoja odpowiedź na to zadziała, ale pamiętaj, że istnieje już automatycznie utworzona metoda dodawania całego zestawu wartości do relacji. Dokumentacja Apple'a ( jak widać tutaj w sekcji „Relacje wielu osób” lub tutaj w sekcji „Niestandardowe metody akcesora relacji”) implementuje je w ten sposób:
Za pomocą tej metody można łatwo skompilować zestaw relacji poza podstawowymi danymi, a następnie dodać je wszystkie naraz. Może być mniej brzydka niż sugerowana metoda;)
źródło
Jestem całkiem pewien, że w końcu został naprawiony w iOS 10 beta 6 !
źródło