executeFetchRequest:error: A fetch request must have an entity.
JustinYangJing opened this issue · 0 comments
MagicalRecord Version: 2.3.2
Xcode:8.3.3
Crash iOS Version :8.x ,9.x
Crash Reason:
A fetch request without entity name .
Entity name is generated by the following function when MagicalRecord alloc a fetch request.
- (NSString *) MR_entityName;
{
NSString *entityName;
if ([self respondsToSelector:@selector(entityName)])
{
entityName = [self performSelector:@selector(entityName)];
}
if ([entityName length] == 0)
{
// Remove module prefix from Swift subclasses
entityName = [NSStringFromClass(self) componentsSeparatedByString:@"."].lastObject;
}
return entityName;
}
The entity name and the class name (a subclass of NSManagedObject) cant be same in Xcode 8.x.
So just get the class name from the MR_entityName ,not the entity name .
if you create *.xcdatamodeld with Xcode 7.x, entity name and the class name are same , so it could get the correct entity name .
Actually , a new function that is call 'fetchRequest' will be auto generated by Xcode 8.x when you select Xcode menu 'Editor | NSManagedObject Subclass '. MagicalRecord could use this function and generate fetch request.
there is no 'fetchRequest' function if the class (a subclass of NSManagedObject) was generated by Xcode 7.x.
So I fix this bug by hooking MR_entityName function .
create a NSManagedObject category. the following is the code .
+(void)load{
Method m1 = class_getClassMethod([self class], @selector(MR_entityName));
Method m2 = class_getClassMethod([self class], @selector(MR_entityNameHook));
method_exchangeImplementations(m1, m2);
}
+(NSString *)MR_entityNameHook{
if ([self respondsToSelector:@selector(fetchRequest)]) {
NSFetchRequest *request = [self fetchRequest];
return request.entityName;
}
return [self MR_entityNameHook];
}