En mi aplicación Lion, tengo este modelo de datos:
La relación subitems
dentroItem
está ordenada .
Xcode 4.1 (compilación 4B110) ha creado para mí el archivo Item.h
, Item.m
,SubItem.h
y SubItem.h
.
Aquí está el contenido (autogenerado) de 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
Y aquí está el contenido (autogenerado) de Item.m
:
#import "Item.h"
#import "SubItem.h"
@implementation Item
@dynamic name;
@dynamic subitems;
@end
Como puede ver, la clase Item
ofrece un método llamado addSubitemsObject:
. Desafortunadamente, cuando trato de usarlo de esta manera:
Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";
SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];
[item addSubitemsObject:subItem];
aparece este error:
2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet
¿Me puedes ayudar?
Actualizar:
Después de solo 1.787 días desde mi informe de errores, hoy (1 de agosto de 2016) Apple me escribió esto: "Verifique este problema con la última versión beta de iOS 10 y actualice su informe de errores en bugreport.apple.com con sus resultados". . Esperemos que este sea el momento adecuado :)
mutableOrderedSetValueForKey:
)Respuestas:
Reproduje su configuración tanto con su modelo de datos como con el mío con diferentes nombres. Obtuve el mismo error en ambos casos.
Parece un error en el código autogenerado de Apple.
fuente
Estoy de acuerdo en que puede haber un error aquí. Modifiqué la implementación del set setter de objetos para que se agregue correctamente a un NSMutableOrderedSet.
La reasignación del conjunto a self.subitems garantizará que se envíen las notificaciones Will / DidChangeValue.
fuente
Decidí mejorar la solución implementando todos los métodos requeridos:
fuente
willChangeValueForKey:withSetMutation:usingObjects
, que has evitado con éxito. Después de eso, solo use[[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values]
o[[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values]
según corresponda. Vea mi respuesta para más detalles.Sí, este es definitivamente un error de Core Data. Escribí una solución basada en ObjC-Runtime hace un tiempo, pero en ese momento pensé que se solucionaría pronto. De todos modos, no tuve tanta suerte, así que lo publiqué en GitHub como KCOrderedAccessorFix . Evite el problema en todas sus entidades:
Una entidad en particular:
O solo para una relación:
fuente
- (BOOL)kc_needsOrderedSetAccessorFix;
o algo que verifique la versión Foundation / iOS.objc_msg_send
)En lugar de hacer una copia, sugiero usar el descriptor de acceso en NSObject para obtener acceso al NSMutableOrderedSet de las relaciones.
por ejemplo, las Notas de lanzamiento de Core Data para iOS v5.0 se refieren a esto.
En una breve prueba funcionó en mi aplicación.
fuente
NSStringFromSelector(@selector(subitems))
embargo, la cadena literal puede ser reemplazada por :)He rastreado el error. Ocurre en
willChangeValueForKey:withSetMutation:usingObjects:
.Esta llamada desencadena una cadena de notificaciones que puede ser difícil de rastrear y, por supuesto, los cambios en un respondedor pueden tener implicaciones para otro, lo que sospecho es por qué Apple no ha hecho nada.
Sin embargo, está bien en Set y solo las operaciones de Set en un OrderedSet funcionan mal. Eso significa que solo hay cuatro métodos que deben modificarse. Por lo tanto, todo lo que hice fue convertir las operaciones Set a sus operaciones Array equivalentes. Estos funcionan perfectamente y los gastos generales mínimos (pero necesarios).
En un nivel crítico, esta solución sufre de un defecto crítico; si está agregando objetos y uno de los objetos ya existe, entonces no se agrega ni se mueve al final de la lista ordenada (no sé cuál). En cualquier caso, el índice ordenado esperado del objeto en el momento en que llegamos
didChange
es diferente de lo previsto. Esto puede romper las aplicaciones de algunas personas, pero no afecta las mías, ya que solo agrego nuevos objetos o confirmo sus ubicaciones finales antes de agregarlos.Por supuesto, hay una solución más fácil. es como sigue;
fuente
Los documentos de Apple para muchos Relaciones dice: usted debe tener acceso al conjunto mutable proxy o conjunto ordenado usando
La modificación de este conjunto agregará o eliminará relaciones a su objeto administrado. Accediendo al conjunto ordenado mutable usando el descriptor de acceso ya sea con [] o. la notación está mal y fallará.
fuente
Recibí el mismo error, la solución @LeeIII funcionó para mí (¡gracias!). Sugiero modificarlo ligeramente:
Contenido de
Item+category.m
:fuente
Si está utilizando mogenerator, entonces en lugar de
simplemente use:
fuente
mogenerator
pero todavía tengo el error.Personalmente, acabo de reemplazar las llamadas a los métodos generados por CoreData con llamadas directas al método como se describe en otra solución de @Stephan:
Esto elimina la necesidad de categorías que luego puedan entrar en conflicto con una solución de Apple para el código generado cuando se corrige el error.
¡Esto tiene la ventaja adicional de ser la forma oficial de hacerlo!
fuente
addObject:
llama dos veces?Parece que si vincula al padre con el hijo estableciendo el padre al hijo y no al revés, funciona sin fallar.
Entonces si lo haces:
en vez de
Debería funcionar, al menos funciona en iOS 7 y no tuvo ningún problema con la relación.
fuente
He tenido el mismo problema, pero solo cuando intenté algo diferente a lo que había estado haciendo. No puedo ver el código para subItem, pero supondré que tiene un enlace inverso al elemento. Llamemos a este enlace de reverencia, "parentItem", entonces la solución más fácil es esta:
El efecto es que hace uso del código propio de Apple y es simple y limpio. Además, el conjunto se agrega automáticamente y todos los observadores se actualizan. No hay problema.
fuente
Simplemente me equivoqué con este problema y lo resolví usando una implementación mucho más simple que las otras descritas aquí. Simplemente uso los métodos disponibles en
NSManagedObject
para tratar las relaciones cuando no uso subclases.Un ejemplo de implementación para insertar una entidad en una
NSOrderedSet
relación se vería así:Esto funciona perfectamente y es lo que estaba usando antes de pasar a las
NSManagedObject
subclases.fuente
Este problema se me ocurrió al migrar un proyecto de Objective-C a Swift 2 con XCode 7 . Ese proyecto solía funcionar, y por una buena razón: estaba usando MOGenerator que tenía métodos de reemplazo para solucionar este error. Pero no todos los métodos requieren un reemplazo.
Así que aquí está la solución completa con una clase de ejemplo, confiando lo más posible en los accesos predeterminados.
Digamos que tenemos una lista con artículos ordenados
Primero, una victoria rápida si tiene una relación uno a muchos, lo más fácil es simplemente hacer:
en vez de
Ahora, si esa no es una opción , esto es lo que puede hacer:
Por supuesto, si está utilizando Objective-C, puede hacer exactamente lo mismo ya que aquí es donde obtuve la idea en primer lugar :)
fuente
Leelll, ¿está seguro de que después de dicha configuración personalizada de valores NSMutableOrderedSet almacenados en ese conjunto CoreData guardará correctamente en la base de datos? No lo comprobé, pero parece que CoreData no sabe nada acerca de NSOrderedSet y espera que NSSet sea un contenedor de muchas relaciones.
fuente
Creo que a todos les falta el verdadero problema. No está en los métodos de acceso sino en el hecho de que
NSOrderedSet
no es una subclase deNSSet
. Entonces, cuando-interSectsSet:
se llama con un conjunto ordenado como argumento, falla.falla con
*** -[NSSet intersectsSet:]: set argument is not an NSSet
Parece que la solución es cambiar la implementación de los operadores de conjunto para que manejen los tipos de forma transparente. No hay razón por la que un
-intersectsSet:
deba funcionar con un conjunto ordenado o no ordenado.La excepción ocurre en la notificación de cambio. Presumiblemente en el código que maneja la relación inversa. Ya que solo sucede si establezco una relación inversa.
Lo siguiente hizo el truco para mí
fuente
Acabo de recibir el problema en Swift (Xcode 6.1.1).
La respuesta fue NO CODIFICAR NINGÚN MÉTODO O COSAS ADICIONALES en sus subclases de NSManagedObject. Creo que es un error del compilador. Muy extraño error ...
Espero eso ayude ..
fuente
Resolví este problema estableciendo el inverso en No inverso, no sé por qué, tal vez haya Apple Bug.
fuente
Tengo la misma situación con un elemento llamado "señales" en lugar de "subpuntos". La solución con tempset funciona en mis pruebas. Además, tuve un problema con removeSignals: método. Esta anulación parece funcionar:
Si hay una mejor manera de hacerlo, avíseme. La entrada de mis valores nunca supera los 10-20 elementos, por lo que el rendimiento no es una gran preocupación; no obstante, señale cualquier cosa relevante.
Gracias,
Damien
fuente
Encontré esta pregunta buscando en Google el mensaje de error, y solo quería señalar que me encontré con este error de una manera ligeramente diferente (sin usar conjuntos ordenados). Esta no es una respuesta a la pregunta dada, pero la estoy publicando aquí en caso de que sea útil para cualquier otra persona que se encuentre con esta pregunta mientras busca.
Estaba agregando una nueva versión del modelo, y agregué algunas relaciones a los modelos existentes, y definí los métodos add * Object en el archivo de encabezado yo mismo. Cuando intenté llamarlos, recibí el error anterior.
Después de revisar mis modelos, me di cuenta de que había olvidado estúpidamente marcar la casilla de verificación "Relación con muchos".
Entonces, si te estás encontrando con esto y no estás usando conjuntos ordenados, revisa tu modelo.
fuente
Encontré una solución para este error que funciona para mí. Acabo de reemplazar esto:
con este:
fuente
Mejor versión de la respuesta correcta en SWIFT
fuente
Descubrí que usar el método de LeeIII funcionaba, pero en la elaboración de perfiles descubrí que era drásticamente lento. Tardó 15 segundos en analizar 1000 artículos. Comentar el código para agregar la relación convirtió 15 segundos en 2 segundos.
Mi solución (que es más rápida pero mucho más fea) implica crear una matriz mutable temporal y luego copiarla en el conjunto ordenado cuando se realiza todo el análisis. (esto es solo una ganancia de rendimiento si va a agregar muchas relaciones).
Espero que esto ayude a alguien más!
fuente
Robert
Estoy de acuerdo en que su respuesta funcionará para esto, pero tenga en cuenta que ya existe un método creado automáticamente para agregar un conjunto completo de valores a una relación. La Documentación de Apple ( como se ve aquí en la sección "Relaciones de muchos a muchos" o aquí en la sección "Métodos personalizados de acceso a muchas relaciones") los implementa de esta manera:
Puede compilar fácilmente su conjunto de relaciones fuera de los datos centrales y luego agregarlos todos a la vez utilizando este método. Puede ser menos feo que el método que sugirió;)
fuente
¡Estoy bastante seguro de que finalmente se solucionó en iOS 10 beta 6 !
fuente