matthewcheok / Realm-JSON

A concise Mantle-like way of working with Realm and JSON.
MIT License
661 stars 129 forks source link

EXC BAD ACCESS when calling createOrUpdateInRealm:withJSONArray: second time. #78

Closed stzseungwon closed 8 years ago

stzseungwon commented 8 years ago
+ (NSDictionary *)mc_inboundMapping {
    static NSMutableDictionary *mappingForClassName = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mappingForClassName = [NSMutableDictionary dictionary];
    });
    @synchronized(mappingForClassName) {
        NSDictionary *mapping = mappingForClassName[[self className]];//<----EXC BAD ACCESS here
        if (!mapping) {
            SEL selector = NSSelectorFromString(@"JSONInboundMappingDictionary");
            if ([self respondsToSelector:selector]) {
                mapping = MCValueFromInvocation(self, selector);
            }
            else {
                mapping = [self mc_defaultInboundMapping];
            }
            mappingForClassName[[self className]] = mapping;
        }
        return mapping;
    }
}

When I attempt to call createOrUpdateInRealm:withJSONArray: multiple time in loop for multiple RLMObjects, the first RLMObject works OK, but the second RLMObject(no matter what class is) fails with EXC BAD ACCESS code1 on static variable. I think autorelease pool deallocate pointing NSMutualDictionary. Anybody got this issue? I'm using xcode 6.3.2 and Realm 0.96.3.

+ (NSArray *)createOrUpdateInRealm:(RLMRealm *)realm withJSONArray:(NSArray *)array {
    NSInteger count = array.count;
    NSMutableArray *result = [NSMutableArray array];

    for (NSInteger index=0; index*kCreateBatchSize<count; index++) {
        NSInteger size = MIN(kCreateBatchSize, count-index*kCreateBatchSize);
        @autoreleasepool
        {
            for (NSInteger subIndex=0; subIndex<size; subIndex++) {
                NSDictionary *dictionary = array[index*kCreateBatchSize+subIndex];
                id object = [self createOrUpdateInRealm:realm withJSONDictionary:dictionary];
                [result addObject:object];
            }
        }
    }

    return [result copy];
}
matthewcheok commented 8 years ago

Maybe this is related to https://github.com/matthewcheok/Realm-JSON/pull/77 - I've just merged and push 0.2.14 for this.

stzseungwon commented 8 years ago

I tried 0.2.14 but got the same result. autoreleasepool deallocates NSMutableDictionary and only static pointer left alive. How about this is? This works fine though. for mc_outboundMapping & mc_inboundMapping

mappingForClassName = [[NSMutableDictionary dictionary] retain];

for mc_classForPropertyKey

set = [[NSCharacterSet characterSetWithCharactersInString:@"\"<"] retain];
stzseungwon commented 8 years ago

I think I found the problem(which was mine). This(R+J) is ARC project and my projects is Non-ARC. So I had to add -fobjc-arc flag in build phase.