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 .
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]; }