Skip to content
This repository

Fix for Ordered Sets Data Import and KVC Issues #440

Closed
wants to merge 1 commit into from

3 participants

Joshua Greene Oleksandr Skrypnyk Marco Chareyron
Joshua Greene

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

Joshua Greene 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
Oleksandr Skrypnyk
sxua commented

:+1: Did the same just right now.

Oleksandr Skrypnyk sxua commented on the diff
...s/NSManagedObject/NSManagedObject+MagicalDataImport.m
((53 lines not shown))
119 131 {
120 132 MRLog(@"Adding object for relationship failed: %@\n", relationshipInfo);
121 133 MRLog(@"relatedObject.entity %@", [relatedObject entity]);
122 134 MRLog(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]);
123   - MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
  135 + MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
124 136 MRLog(@"perform selector error: %@", exception);
1
Oleksandr Skrypnyk
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
Marco Chareyron

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.

Joshua Greene

@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.

Marco Chareyron

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

Showing 1 unique commit by 1 author.

Mar 29, 2013
Joshua Greene 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
This page is out of date. Refresh to see the latest.
34 MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m
@@ -89,38 +89,50 @@ - (NSManagedObject *) MR_findObjectForRelationship:(NSRelationshipDescription *)
89 89
90 90 - (void) MR_addObject:(NSManagedObject *)relatedObject forRelationship:(NSRelationshipDescription *)relationshipInfo
91 91 {
92   - NSAssert2(relatedObject != nil, @"Cannot add nil to %@ for attribute %@", NSStringFromClass([self class]), [relationshipInfo name]);
  92 + NSAssert2(relatedObject != nil, @"Cannot add nil to %@ for attribute %@", NSStringFromClass([self class]), [relationshipInfo name]);
93 93 NSAssert2([relatedObject entity] == [relationshipInfo destinationEntity], @"related object entity %@ not same as destination entity %@", [relatedObject entity], [relationshipInfo destinationEntity]);
94   -
  94 +
95 95 //add related object to set
96 96 NSString *addRelationMessageFormat = @"set%@:";
97 97 id relationshipSource = self;
98   - if ([relationshipInfo isToMany])
  98 + if ([relationshipInfo isToMany])
99 99 {
100 100 addRelationMessageFormat = @"add%@Object:";
  101 +
101 102 if ([relationshipInfo respondsToSelector:@selector(isOrdered)] && [relationshipInfo isOrdered])
102 103 {
103 104 //Need to get the ordered set
104   - NSString *selectorName = [[relationshipInfo name] stringByAppendingString:@"Set"];
105   - relationshipSource = [self performSelector:NSSelectorFromString(selectorName)];
  105 + relationshipSource = [self performSelector:NSSelectorFromString([relationshipInfo name])];
106 106 addRelationMessageFormat = @"addObject:";
107 107 }
108 108 }
109   -
  109 +
110 110 NSString *addRelatedObjectToSetMessage = [NSString stringWithFormat:addRelationMessageFormat, attributeNameFromString([relationshipInfo name])];
111   -
  111 +
112 112 SEL selector = NSSelectorFromString(addRelatedObjectToSetMessage);
113 113
114   - @try
  114 + if ([relationshipSource respondsToSelector:selector])
115 115 {
116   - [relationshipSource performSelector:selector withObject:relatedObject];
  116 + if (relationshipSource != self)
  117 + {
  118 + NSUInteger idx = [relationshipSource count];
  119 + NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
  120 +
  121 + [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:[relationshipInfo name]];
  122 + [relationshipSource performSelector:selector withObject:relatedObject];
  123 + [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:[relationshipInfo name]];
  124 + }
  125 + else
  126 + {
  127 + [relationshipSource performSelector:selector withObject:relatedObject];
  128 + }
117 129 }
118   - @catch (NSException *exception)
  130 + else
119 131 {
120 132 MRLog(@"Adding object for relationship failed: %@\n", relationshipInfo);
121 133 MRLog(@"relatedObject.entity %@", [relatedObject entity]);
122 134 MRLog(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]);
123   - MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
  135 + MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
124 136 MRLog(@"perform selector error: %@", exception);
125 137 }
126 138 }

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.