drewmccormack / ensembles

A synchronization framework for Core Data.
MIT License
1.63k stars 131 forks source link

ordered relationships is crash #192

Closed iiiyu closed 9 years ago

iiiyu commented 9 years ago

hi @drewmccormack

I tested the 1.x version of Ensembles, it turns that App would crash if I had used relationships in my data model. Does the problem have been repaired in 2.x version? We are evaluating the sync solutions. Ensembles would be the best one, if it can solve the problem of ordered relationships. Certainly, we will pay for it. Hope for your reply!

https://github.com/drewmccormack/ensembles/blob/d62fbf396726785a3184d42e66831bfbfd6c5d9c/Framework/Source/Events/CDEEventIntegrator.m#L793

like is

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableOrderedSet sortRange:options:usingComparator:]: range {0, 2} extends beyond bounds for empty ordered set'
drewmccormack commented 9 years ago

Strange. Will check this out Monday.

Kind regards, Drew

On 17 Oct 2014, at 1:42 pm, ChenYu Xiao notifications@github.com wrote:

hi @drewmccormack

I tested the 1.x version of Ensembles, it turns that App would crash if I had used relationships in my data model. Does the problem have been repaired in 2.x version? We are evaluating the sync solutions. Ensembles would be the best one, if it can solve the problem of ordered relationships. Certainly, we will pay for it. Hope for your reply!

https://github.com/drewmccormack/ensembles/blob/d62fbf396726785a3184d42e66831bfbfd6c5d9c/Framework/Source/Events/CDEEventIntegrator.m#L793

like is

* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSMutableOrderedSet sortRange:options:usingComparator:]: range {0, 2} extends beyond bounds for empty ordered set' — Reply to this email directly or view it on GitHub.

iiiyu commented 9 years ago

I think is a Apple bug.

I replace this line

https://github.com/drewmccormack/ensembles/blob/d62fbf396726785a3184d42e66831bfbfd6c5d9c/Framework/Source/Events/CDEEventIntegrator.m#L763

to

        SEL selector = NSSelectorFromString([@"primitive" stringByAppendingString:relationshipChange.propertyName]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        NSMutableOrderedSet *relatedObjects =  [object performSelector:selector];
#pragma clang diagnostic pop

It will not crash.

NSMutableOrderedSet *relatedObjects = [object mutableOrderedSetValueForKey:relationshipChange.propertyName];

is

po [relatedObjects class]
_NSProxyWrapperMutableOrderedSet

replace after

 po [relatedObjects class]
_NSFaultingMutableOrderedSet

I do not know why this problem occurs. Will this replace the code will be other questions?

drewmccormack commented 9 years ago

Using the primitive value is not a good solution, because it won't fire KVO, and that is needed by the managed object context. It is odd that you see this problem. I haven't see it before, and there are unit tests for ordered relationships. What OS are you testing on?

Could you try this instead?

    NSMutableOrderedSet *relatedObjects = [[object valueForKey:relationshipChange.propertyName] mutableCopy];

and then at the bottom of the loop, add this

[object setValue:relatedObjects forKey:relationshipChange.propertyName];

Can you let me know if that works? If you want to test if this is a problem in version 2, email me at drewmccormack@mac.com

drewmccormack commented 9 years ago

Any news on this?

iiiyu commented 9 years ago

@drewmccormack

 NSMutableOrderedSet *relatedObjects = [[object valueForKey:relationshipChange.propertyName] mutableCopy];
[object setValue:relatedObjects forKey:relationshipChange.propertyName];

It work. But my code has other synchronization problems. May be a problem mogenerator production code. I'm still looking in. Thanks for your help

drewmccormack commented 9 years ago

Let me know if you figure this out, because I haven't heard of the problem from others, so I am wondering if this might just have something to do with your setup. If it really is a bug, I would like to fix it.

iiiyu commented 9 years ago

Sorry now reply. Recently too busy. Originally, I wanted to write a demo but did not have time to write.

It is my test model

I use mogenerator production ordered relationships code like

@interface _GDDiary (GridsCoreDataGeneratedAccessors)
- (void)addGrids:(NSOrderedSet*)value_;
- (void)removeGrids:(NSOrderedSet*)value_;
- (void)addGridsObject:(GDGrid*)value_;
- (void)removeGridsObject:(GDGrid*)value_;

- (void)insertObject:(GDGrid*)value inGridsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromGridsAtIndex:(NSUInteger)idx;
- (void)insertGrids:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeGridsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInGridsAtIndex:(NSUInteger)idx withObject:(GDGrid*)value;
- (void)replaceGridsAtIndexes:(NSIndexSet *)indexes withGrids:(NSArray *)values;
@end

If I use the above method.

My ordered relationships became _NSProxyWrapperMutableOrderedSet.

I found this https://github.com/JaviSoto/iOS8-Runtime-Headers/blob/master/Frameworks/CoreData.framework/_NSProxyWrapperMutableOrderedSet.h

_NSProxyWrapperMutableOrderedSet Though NSMutableOrderedSet subclasses. But it does not work.

So, My current solution is

 GDDiary *diary = blablabla;
NSMutableOrderedSet *orderedGrids = [diary.grids mutableCopy];
// orderedGrids add grid or remove grid
diary.grids =  [orderedGrids copy]