Weird Core Data Reaction - Not Detecting NSManaged

2019-09-01 01:20发布

问题:

There seems to be a very weird bug in my app in which I'm using Core Data.

I handled everything required already, and it was working for like past recent weeks.

I closed the project yesterday, and started development today ( with no modifications in code ) and now every time I wanna add a row to my database, I get an exception saying the following class is not a subclass of NSManagedObject, which I'm ridiculously sure is not true, first because it was working for days, and second because I generated them automatically as NSManagedObject subclasses. I tried regenerating classes using Editor->Create NSManagedObject Subclasses in my data model, but it didn't help me at all.

It's really weird that I get this exception out of blue and all of a sudden WITHOUT EVEN A LINE OF MODIFICATION in my code :(

Anybody got any idea ? I really appreciate any help. Thanks

BTW, Here're some code that may help :

The Error :

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '"Message" is not a subclass of NSManagedObject.

Message Class Header File (Auto-Generated) :

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class File;

@interface Message : NSManagedObject

@property (nonatomic, retain) NSString * data;
@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) NSString * fileId;
@property (nonatomic, retain) NSString * number;
@property (nonatomic, retain) NSString * status;
@property (nonatomic, retain) NSString * type;
@property (nonatomic, retain) NSString * xmppId;
@property (nonatomic, retain) File *contains;

@end

The method in which I try to create a new message object :

+ (void)sendXMPPMessage:(NSString *)messageStr containingFile:(NSData *)fileData toNumber:(NSString *)number
{
    if(fileData == nil)
    {
        NSString *newID = [self generateNewXMPPMessageID];

        SunBirdAppDelegate *appDelegate = (SunBirdAppDelegate *)[[UIApplication sharedApplication] delegate];
        [appDelegate sendXMPPMessage:messageStr withID:newID toNumber:number];

        NSMutableDictionary *messageDataDic = [[NSMutableDictionary alloc] init];

        [messageDataDic setObject:messageStr forKey:@"body"];
        [messageDataDic setObject:@"Outgoing" forKey:@"type"];
        [messageDataDic setObject:newID forKey:@"xmppId"];
        [messageDataDic setObject:@"Sending" forKey:@"status"];
        [messageDataDic setObject:[NSDate date] forKey:@"date"];
        [messageDataDic setObject:number forKey:@"number"];

        [Message messageWithMessageInfo:messageDataDic inManagedObjectContext:[appDelegate managedObjectContext]];
    }
    else
    {
        //Handle Database With File Data
    }
}

Creating a New Message Object -> The Create Category On Message Class (Message+Create.m) :

+ (Message *)messageWithMessageInfo:(NSDictionary *)messageInfo inManagedObjectContext:(NSManagedObjectContext *)context
{
    SunBirdAppDelegate *appDelegate = (SunBirdAppDelegate *)[[UIApplication sharedApplication] delegate];

    Message *newMessage = nil;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Message"];
    request.predicate = [NSPredicate predicateWithFormat:@"xmppId = %@", [messageInfo objectForKey:@"msgId"]];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"xmppId" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *matches = [context executeFetchRequest:request error:&error];

    if (!matches || ([matches count] > 1))
    {
        // handle error
    }
    else if ([matches count] == 0)
    {
        newMessage = [NSEntityDescription insertNewObjectForEntityForName:@"Message" inManagedObjectContext:context];
        newMessage.data = [messageInfo objectForKey:@"body"];
        newMessage.type = [messageInfo objectForKey:@"type"];
        newMessage.date = [messageInfo objectForKey:@"date"];
        newMessage.xmppId = [messageInfo objectForKey:@"xmppId"];
        newMessage.status = [messageInfo objectForKey:@"status"];
        newMessage.number = [messageInfo objectForKey:@"number"];

        if ( [[messageInfo allKeys] containsObject:@"fileId"] )
        {
            newMessage.fileId = [messageInfo objectForKey:@"fileId"];
            newMessage.contains = [messageInfo objectForKey:@"fileData"];
        }
        else
        {
            newMessage.fileId = NULL;
            newMessage.contains = NULL;
        }
    }
    else
    {
        newMessage = [matches lastObject];
        NSLog(@"WARNING : NO NEW MESSAGE STORED IN DB ! MESSAGE WITH SAME XMPPID RETURNED");
    }
    [appDelegate saveContext];
    return newMessage;
}

And this is the line on which I'm being informed Message is not a subclass of NSManagedObject :

newMessage = [NSEntityDescription insertNewObjectForEntityForName:@"Message" inManagedObjectContext:context];

回答1:

This is a bug i stumbled on in a project I worked on.

Message cannot be used an an entity name ... why? ... Apple ... ???

Don't really know.

Rename to something else and this usually solve the problem.