Question

I am mapping two classes of objects with RestKit. When I do either of them by themselves, it works out perfectly fine. But when I call them together, it will crash on line 449 in RKObjectMappingOperation.m,

[destinationSet setSet:destinationObject];

With an "EXC_BAD_ACCESS" error.

Here are my two mapping methods:

- (RKObjectLoader *)saves
{
    // Create an object manager and connect core data's persistent store to it
    RKObjectManager *objectManager = [RKObjectManager sharedManager];
    RKManagedObjectStore* objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"Db.sqlite"];
    objectManager.objectStore = objectStore;

    // Define our author mapping for saved places
    RKManagedObjectMapping *authorMapping = [RKManagedObjectMapping mappingForEntityWithName:@"Person"];
    [authorMapping mapAttributes:@"uid", nil];

    // Define our place mapping
    RKManagedObjectMapping *placeMapping = [RKManagedObjectMapping mappingForEntityWithName:@"Place"];
    [placeMapping mapAttributes:@"uid",@"name",@"address", nil];

    // Now, connect the two via a save
    RKManagedObjectMapping *saveMapping = [RKManagedObjectMapping mappingForEntityWithName:@"Save"];
    [saveMapping mapAttributes:@"uid", @"timestamp", nil];

    [saveMapping mapKeyPath:@"place" toRelationship:@"place" withMapping:placeMapping];
    [saveMapping mapKeyPath:@"author" toRelationship:@"author" withMapping:authorMapping];

    // We expect to find the place entity inside of a dictionary keyed "saves"
    [objectManager.mappingProvider setMapping:saveMapping forKeyPath:@"saves"];

    // Prepare our object loader to load and map objects from remote server, and send
    RKObjectLoader *objectLoader = [objectManager objectLoaderWithResourcePath:@"places/saves" delegate:self];
    objectLoader.method = RKRequestMethodGET;
    [objectLoader send];

    return objectLoader;
}

- (RKObjectLoader *)recommends
{
    // Create an object manager and connect core data's persistent store to it
    RKObjectManager *objectManager = [RKObjectManager sharedManager];
    RKManagedObjectStore* objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"Db.sqlite"];
    objectManager.objectStore = objectStore;

    // Define our author mapping for recommended places
    RKManagedObjectMapping *authorMapping = [RKManagedObjectMapping mappingForEntityWithName:@"Person"];
    [authorMapping mapAttributes:@"uid", nil];

    // Define our place mapping
    RKManagedObjectMapping *placeMapping = [RKManagedObjectMapping mappingForEntityWithName:@"Place"];
    [placeMapping mapAttributes:@"uid",@"name",@"address", nil];

    // Now, connect the two via a recommend
    RKManagedObjectMapping *recommendMapping = [RKManagedObjectMapping mappingForEntityWithName:@"Recommend"];
    [recommendMapping mapAttributes:@"uid", @"timestamp", nil];

    [recommendMapping mapKeyPath:@"place" toRelationship:@"place" withMapping:placeMapping];
    [recommendMapping mapKeyPath:@"author" toRelationship:@"author" withMapping:authorMapping];

    // We expect to find the place entity inside of a dictionary keyed "recommends"
    [objectManager.mappingProvider setMapping:recommendMapping forKeyPath:@"recommends"];

    // Prepare our object loader to load and map objects from remote server, and send
    RKObjectLoader *objectLoader = [objectManager objectLoaderWithResourcePath:@"places/recommends" delegate:self];
    objectLoader.method = RKRequestMethodGET;
    [objectLoader send];

    return objectLoader;
}

When I call one, or the other, it works. When I call both,

[self saves];
[self recommends];

It crashes. Any idea why?

Was it helpful?

Solution

The call to set objectManager.objectStore is causing the previously set objectStore to be released from objectManager. The first call, [self saves] creates and sets an objectStore object, then second call [self recommends] repeats this, thereby removing the first one set in [self saves]. Some time during the processing started off by [self saves], the original (released) objectStore object is being accessed, hence the crash.

A potential fix would be to refactor out the objectStore setter into a separate method which is called by both methods, or wrap it in an if (!objectManager.objectStore) { ... } statement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top