RestKit自反关系实体无限循环

时间:2013-08-04 14:25:20

标签: loops restkit relationship

这是RestKit中的错误还是我没有正确配置? 使用以下映射时,我得到一个无限循环:

JSON:

[
{
    "name": "Test 1",
    "subtests": [
        {
            "name": "Subtest 1"
        },
        {
            "name": "Subtest 2"
        },
        {
            "name": "Subtest 3"
        }
    ],
    "children": ["Test 1"]
},
{
    "name": "Test 2",
    "subtests": [
        {
            "name": "Subtest 4"
        },
        {
            "name": "Subtest 5"
        },
        {
            "name": "Subtest 6"
        }
    ],
    "children": ["Test 2"]
}
]

映射提供商:

+ (RKMapping *)testMapping
{
    RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];

    mapping.identificationAttributes = @[ @"name" ];

    [mapping addAttributeMappingsFromArray:@[ @"name" ]];

    [mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:[MappingProvider reflexiveTestMapping]]];
    [mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"subtests" toKeyPath:@"subtests" withMapping:[MappingProvider subTestMapping]]];

    return mapping;
}

+ (RKMapping *)reflexiveTestMapping
{
    RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];

    mapping.identificationAttributes = @[ @"name" ];

    [mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"name" withMapping:[MappingProvider testMapping]]];

    return mapping;
}

+ (RKMapping *)subTestMapping;
{
    RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([SubTest class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];

    mapping.identificationAttributes = @[ @"name" ];

    [mapping addAttributeMappingsFromArray:@[ @"name" ]];

    return mapping;    
}

我从这里叫它:

- (IBAction)loadTestAndSubtestEntity:(id)sender {
    RKLogConfigureByName("RestKit", RKLogLevelWarning);
    RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
    RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);

    NSString *filePathComponent = [self.pathComponent     stringByAppendingPathComponent:@"test.json"];
    [[InfoDataModel sharedDataModel] importDataFromJsonFilePathComponent:filePathComponent withMapping:[MappingProvider testMapping]];
}

因为它挂起而没有生成输出: self.storePath使用文件路径初始化。

- (void)importDataFromJsonFilePathComponent:(NSString *)jsonFilePathComponent withMapping:(RKMapping *)mapping
{
    if (self.storePath) {
        NSString *jsonFilePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:jsonFilePathComponent];
        MyLog(@"InfoDataModel. JSON file: %@", jsonFilePath);
        RKManagedObjectImporter *importer = [[RKManagedObjectImporter alloc] initWithManagedObjectModel:self.objectStore.managedObjectModel storePath:self.storePath];
        importer.resetsStoreBeforeImporting = NO;
        MyLog(@"InfoDataModel. Store: %@", self.storePath);

        NSError *error = nil;
        [importer importObjectsFromItemAtPath:jsonFilePath
                                  withMapping:mapping
                                      keyPath:nil
                                        error:&error];

        BOOL success = [importer finishImporting:&error];
        if (success) {
            [importer logSeedingInfo];
        }
    }
}

4 个答案:

答案 0 :(得分:1)

问题是你有两个相互呼叫的方法。 testMapping方法由于以下行调用reflexiveTestMapping方法:

[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:[MappingProvider reflexiveTestMapping]]];

reflexiveTestMapping方法由于以下行而调用testMapping方法:

[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"name" withMapping:[MappingProvider testMapping]]];

这是一个硬性循环,与映射没有任何直接关系,只与您尝试创建映射的方式有关。

不需要以这种方式创建映射,因为JSON中的children关系仅包含名称,而不是完整对象。

答案 1 :(得分:0)

此递归中的一个“解决方案”是限制基于递归调用的最大数量 估计跳跃,在这种情况下两次跳跃。

+ (RKMapping *)reflexiveTestMapping
{
    RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];

    mapping.identificationAttributes = @[ @"name" ];

    // No more recursion calls from this point

    return mapping;
}

答案 2 :(得分:0)

这是我修复递归的方法:

+ (RKMapping *)testMapping
{
    RKEntityMapping *innerMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
    innerMapping.identificationAttributes = @[ @"name" ];

    RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
    mapping.identificationAttributes = @[ @"name" ];
    [mapping addAttributeMappingsFromArray:@[ @"name" ]];

    [mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:innerMapping]];

    return mapping;
}

答案 3 :(得分:0)

这就是我用swift做的事情

<div class="imageContainer">
<div class="textContainer">
    <h1>Spider Man</h1>
    <span>This is test</span>
</div>
<img id="img1" src="http://images.indianexpress.com/2015/07/spiderman-new.jpg" width="500px" />
</div>