GrahamDennis / GDCoreDataConcurrencyDebugging

GDCoreDataConcurrencyDebugging helps you find cases where NSManagedObject's are being called on the wrong thread or dispatch queue.
MIT License
170 stars 23 forks source link

Mismatched class names - more swizzling required? #15

Closed ericrisler closed 10 years ago

ericrisler commented 10 years ago

Hi,

I've noticed that after linking to your project getting the class name using NSStringFromClass(self) does not match the value from calling NSEntityDescription -managedObjectClassName.

As a contrived example:

MyClass *mc = (...);
NSString *myClassName = NSStringFromClass(mc); // equals 'MyClass'

NSArray *entityDescriptions = [[[managedObjectContext persistentStoreCoordinator] managedObjectModel] entities];

NSEntityDescription *thisDescription = nil;
for( NSEntityDescription *eachEntity in entityDescriptions ) {
    /* [eachEntity managedObjectClassName] evaluates to 'MyClass_GDCoreDataConcurrencyDebugging' */
    if( [[eachEntity managedObjectClassName] isEqualToString: myClassName e] ) {
        thisDescription = eachEntity;
        break;
    }
}

I wouldn't file this as a bug but perhaps you can add more swizzling so that existing code that uses NSStringFromClass can function as expected after linking to your project.

Thanks for the great project!

GrahamDennis commented 10 years ago

Can you explain why you would need this behaviour? I explicitly overrode the -class method in the swizzling to ensure that NSStringFromClass() and other things wouldn't change after linking to GDCoreDataConcurrencyDebugging.

Your logic above doesn't seem particularly safe either. Key-Value Observing can create custom, dynamic subclasses similar to how GDCoreDataConcurrencyDebugging works. It's probable that CoreData directly supports KVO, so KVO won't create those custom subclasses and this may not be an issue in practice. However, the actual logic you're looking for is probably something like:

[[mc class] isKindOfClass:NSClassFromString([eachEntity managedObjectClassName])];
ericrisler commented 10 years ago

Ah - I see the difference. To answer your question as to why one would need the code I used as an example: I'm not certain to be honest as I didn't write it. Using isKindOfClass: is going to produce the expected result. Thanks.