2

This is the strangest error I've ever had, simply because I can't find any information on it anywhere.

Background:

I have an app using RestKit (current master) that maps to Core Data. I'm using a custom mapping provider (subclass of RKObjectMappingProvider). This generates all of the mappings that I need, similar to the RKGithub project.

Some of my objects have many-to-many relationships, so I have to register some of the relationships (in the mapping provider) after the others are set up to avoid an infinite recursion. (Friends has_many Friends has_many Friends...)

When the app runs and RestKit configures itself, an error occurs on this line (in RKManagedObjectStore.m)

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_managedObjectModel];

I can't step into the "initWithManagedObjectModel:" method. The only information I get is this exception in the logs:

-[NSSQLToMany _setInverseManyToMany:]: unrecognized selector sent to instance 0xcc78890

I have no idea what caused this or how to fix it. I can't find any documentation on it or even anyone who's had this problem before. All I could find was this dump of the iOS framework:

public struct NSSQLManyToMany : IEquatable<NSSQLManyToMany> {
        internal NObjective.RuntimeObject Handle;
        public static readonly RuntimeClass ClassHandle = CoreDataCachedClasses.NSSQLManyToMany;
        public static implicit operator IntPtr( NSSQLManyToMany value ) {
            return value.Handle;
        }
        public static implicit operator NObjective.RuntimeObject( NSSQLManyToMany value ) {
            return value.Handle;
        }
        public override bool Equals( object value ) {
            var compareTo = value as NSSQLManyToMany?;
            return compareTo != null && Handle == compareTo.Value.Handle;
        }
        public bool Equals( NSSQLManyToMany value ) {
            return Handle == value.Handle;
        }
        public static bool operator ==( NSSQLManyToMany value1, NSSQLManyToMany value2 ) {
            return value1.Handle == value2.Handle;
        }
        public static bool operator !=( NSSQLManyToMany value1, NSSQLManyToMany value2 ) {
            return value1.Handle != value2.Handle;
        }
        public NSSQLManyToMany( IntPtr value ) {
            this.Handle = new RuntimeObject( value );
        }
        public static NSSQLManyToMany alloc() {
            return new NSSQLManyToMany( ClassHandle.InvokeIntPtr( Selectors.alloc ) );
        }
        unsafe public NObjective.RuntimeObject inverseColumnName() {
            RuntimeObject ___occuredException;
            var ___result = NativeMethods.inverseColumnName( Handle, CachedSelectors.inverseColumnName, out ___occuredException, 0 );
            if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException ); 
            return new NObjective.RuntimeObject( ___result );
        }
        unsafe public NObjective.RuntimeObject inverseManyToMany() {
            RuntimeObject ___occuredException;
            var ___result = NativeMethods.inverseManyToMany( Handle, CachedSelectors.inverseManyToMany, out ___occuredException, 0 );
            if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException ); 
            return new NObjective.RuntimeObject( ___result );
        }
        unsafe public bool isMaster() {
            RuntimeObject ___occuredException;
            var ___result = NativeMethods.isMaster( Handle, CachedSelectors.isMaster, out ___occuredException, 0 );
            if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException ); 
            return ___result;
        }
        unsafe public bool isReflexive() {
            RuntimeObject ___occuredException;
            var ___result = NativeMethods.isReflexive( Handle, CachedSelectors.isReflexive, out ___occuredException, 0 );
            if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException ); 
            return ___result;
        }
        private static class NativeMethods {
            [DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
            public static extern IntPtr inverseColumnName( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
            [DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
            public static extern IntPtr inverseManyToMany( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
            [DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
            public static extern bool isMaster( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
            [DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
            public static extern bool isReflexive( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
        }
        static internal class CachedSelectors {
            public static readonly Selector inverseColumnName = "inverseColumnName";
            public static readonly Selector inverseManyToMany = "inverseManyToMany";
            public static readonly Selector isMaster = "isMaster";
            public static readonly Selector isReflexive = "isReflexive";
        }
    }

Which very clearly seems to have a setter:

public NSSQLManyToMany( IntPtr value ) {
        this.Handle = new RuntimeObject( value );
    }

Any ideas?

EDIT: I should add that I've tried all of the "simple" solutions. Deleting the app from the sim doesn't work.

I suspect that it might be because I have an entity that has two "has and belongs to many" relationships with the same (different) entity. But I can't see why that would be an actual problem.

4

1 に答える 1

1

Just figured this out!

I had two relationships on one entity pointing to another entity, and they inadvertently had the same inverse.

To illustrate:

Part:
   has many (Car*)cars, inverse parts
   has one (Car*)deliveryTruck, inverse parts 

A bit contrived, but the idea is there. I had to change the second parts to some other property.

Hopefully this will help someone else with the same cryptic error message. You'd expect clang to warn you about something like this! (It freaks out enough as it is if you don't have an inverse at all).

于 2012-10-14T23:04:33.000 に答える