Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix for Ordered Sets Data Import and KVC Issues #440

Closed
wants to merge 1 commit into from

3 participants

@JRG-Developer

Building on @cheneveld 's solution to fix data import for ordered sets, this code invokes the appropriate access and change notifications on self, which is required for Core Data to correctly set the inverse relationship on the related object

@JRG-Developer JRG-Developer Building on @cheneveld 's solution to fix data import for ordered set…
…s, this code invokes the appropriate access and change notifications on self, which is required for Core Data to correctly set the inverse relationship on the related object
b1158fb
@sxua

:+1: Did the same just right now.

@sxua sxua commented on the diff
...s/NSManagedObject/NSManagedObject+MagicalDataImport.m
((53 lines not shown))
{
MRLog(@"Adding object for relationship failed: %@\n", relationshipInfo);
MRLog(@"relatedObject.entity %@", [relatedObject entity]);
MRLog(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]);
- MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
+ MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
MRLog(@"perform selector error: %@", exception);
@sxua
sxua added a note

This line is incorrect. We have no exception variable anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@charex

Hi,
I have exactly the same problem while importing a one-toMany relationship, with a crash due to an NSInvalidArgumentException (the new selector with the "Set" causes an unrecognized selector).

I've tried your patch and it solved my problem. I was wondering why it wasn't merged in MR, I'm currently using version 2.2 (from CocoaPods), but also the current developer branch has no trace of your patch. Why did you close this issue? Did you find an alternative solution? Thank you.

@JRG-Developer

@charex

I don't remember why I closed this exactly... it may be because there are several competing pulls pending? Or it didn't match up with the latest dev branch...?

Either way, I don't think this pull request has any chance of ever being pulled into the main repo. Mainly because

1) it's an Apple bug;
2) it lacks unit tests (I've just started writing unit tests for my own code and didn't here);
3) yet most importantly, MagicalRecord's authors use mogenerator. Mogenerator's current master branch has something of a fix for this already -- it creates NSMutableSet and NSMutableOrderedSet properties for the unordered and ordered to-many relationships respectively.

I was lazy, however, and didn't want to go back and rewrite all of my code to use these properties. So instead, I created a patch that adds "fixed" methods for ordered sets to the computer-version of the generated models.

See this pull request:

rentzsch/mogenerator#181

For me, this is a better solution than having this "fix" included in MagicalRecord... mogenerator was designed to make CoreData work better than the junk Apple provides by default, so I think it's more appropriate that the fix go there for this.

For these reasons, I am leaving this pull request closed.

@charex

Hi @JRG-Developer,
thanks for your answer, I've really appreciated its completeness.
I've ended using Mogenerator (I was already planning to use it), it seems a better solution than patching manually this file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 29, 2013
  1. @JRG-Developer

    Building on @cheneveld 's solution to fix data import for ordered set…

    JRG-Developer authored
    …s, this code invokes the appropriate access and change notifications on self, which is required for Core Data to correctly set the inverse relationship on the related object
This page is out of date. Refresh to see the latest.
View
34 MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m
@@ -89,38 +89,50 @@ - (NSManagedObject *) MR_findObjectForRelationship:(NSRelationshipDescription *)
- (void) MR_addObject:(NSManagedObject *)relatedObject forRelationship:(NSRelationshipDescription *)relationshipInfo
{
- NSAssert2(relatedObject != nil, @"Cannot add nil to %@ for attribute %@", NSStringFromClass([self class]), [relationshipInfo name]);
+ NSAssert2(relatedObject != nil, @"Cannot add nil to %@ for attribute %@", NSStringFromClass([self class]), [relationshipInfo name]);
NSAssert2([relatedObject entity] == [relationshipInfo destinationEntity], @"related object entity %@ not same as destination entity %@", [relatedObject entity], [relationshipInfo destinationEntity]);
-
+
//add related object to set
NSString *addRelationMessageFormat = @"set%@:";
id relationshipSource = self;
- if ([relationshipInfo isToMany])
+ if ([relationshipInfo isToMany])
{
addRelationMessageFormat = @"add%@Object:";
+
if ([relationshipInfo respondsToSelector:@selector(isOrdered)] && [relationshipInfo isOrdered])
{
//Need to get the ordered set
- NSString *selectorName = [[relationshipInfo name] stringByAppendingString:@"Set"];
- relationshipSource = [self performSelector:NSSelectorFromString(selectorName)];
+ relationshipSource = [self performSelector:NSSelectorFromString([relationshipInfo name])];
addRelationMessageFormat = @"addObject:";
}
}
-
+
NSString *addRelatedObjectToSetMessage = [NSString stringWithFormat:addRelationMessageFormat, attributeNameFromString([relationshipInfo name])];
-
+
SEL selector = NSSelectorFromString(addRelatedObjectToSetMessage);
- @try
+ if ([relationshipSource respondsToSelector:selector])
{
- [relationshipSource performSelector:selector withObject:relatedObject];
+ if (relationshipSource != self)
+ {
+ NSUInteger idx = [relationshipSource count];
+ NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
+
+ [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:[relationshipInfo name]];
+ [relationshipSource performSelector:selector withObject:relatedObject];
+ [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:[relationshipInfo name]];
+ }
+ else
+ {
+ [relationshipSource performSelector:selector withObject:relatedObject];
+ }
}
- @catch (NSException *exception)
+ else
{
MRLog(@"Adding object for relationship failed: %@\n", relationshipInfo);
MRLog(@"relatedObject.entity %@", [relatedObject entity]);
MRLog(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]);
- MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
+ MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
MRLog(@"perform selector error: %@", exception);
@sxua
sxua added a note

This line is incorrect. We have no exception variable anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
}
Something went wrong with that request. Please try again.