Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
核心数据-iPhone上的JSON(TouchJSON)_Iphone_Objective C_Json_Core Data - Fatal编程技术网

核心数据-iPhone上的JSON(TouchJSON)

核心数据-iPhone上的JSON(TouchJSON),iphone,objective-c,json,core-data,Iphone,Objective C,Json,Core Data,我有下面的代码,它似乎一直持续到应用程序崩溃。这似乎发生在datastructureFromManagedObject方法中的递归中。我怀疑这种方法: 1) 查看第一个托管对象并递归遵循任何关系属性。 2) 检查在第1点找到的关系的另一端的对象,并重复该过程 如果管理的对象A与对象B存在一对多关系,并且这种关系是双向的(即从B到A的关系是反向的-例如,一个部门有许多员工,但每个员工只有一个部门)下面的代码陷入无限递归,因为它遵循从对象B到对象A的一对一关系,依此类推 如果是这样的话,有谁能提供一

我有下面的代码,它似乎一直持续到应用程序崩溃。这似乎发生在datastructureFromManagedObject方法中的递归中。我怀疑这种方法:

1) 查看第一个托管对象并递归遵循任何关系属性。 2) 检查在第1点找到的关系的另一端的对象,并重复该过程

如果管理的对象A对象B存在一对多关系,并且这种关系是双向的(即从BA的关系是反向的-例如,一个部门有许多员工,但每个员工只有一个部门)下面的代码陷入无限递归,因为它遵循从对象B对象A的一对一关系,依此类推

如果是这样的话,有谁能提供一个解决方案,这样我就可以将托管对象的整个对象图转换为JSON

#import "JSONUtils.h"


@implementation JSONUtils

- (NSDictionary*)dataStructureFromManagedObject:(NSManagedObject *)managedObject {

    NSDictionary *attributesByName = [[managedObject entity] attributesByName];
    NSDictionary *relationshipsByName = [[managedObject entity] relationshipsByName];

    //getting the values correspoinding to the attributes collected in attributesByName
    NSMutableDictionary *valuesDictionary = [[managedObject dictionaryWithValuesForKeys:[attributesByName allKeys]] mutableCopy];

    //sets the name for the entity being encoded to JSON
    [valuesDictionary setObject:[[managedObject entity] name] forKey:@"ManagedObjectName"];

    NSLog(@"+++++++++++++++++> before the for loop");
    //looks at each relationship for the given managed object
    for (NSString *relationshipName in [relationshipsByName allKeys]) {
        NSLog(@"The relationship name = %@",relationshipName);
        NSRelationshipDescription *description = [relationshipsByName objectForKey:relationshipName];

        if (![description isToMany]) {
            NSLog(@"The relationship is NOT TO MANY!");
            [valuesDictionary setObject:[self dataStructureFromManagedObject:[managedObject valueForKey:relationshipName]] forKey:relationshipName];
            continue;
        }
        NSSet *relationshipObjects = [managedObject valueForKey:relationshipName];
        NSMutableArray *relationshipArray = [[NSMutableArray alloc] init];
        for (NSManagedObject *relationshipObject in relationshipObjects) {
            [relationshipArray addObject:[self dataStructureFromManagedObject:relationshipObject]];
        }
        [valuesDictionary setObject:relationshipArray forKey:relationshipName];
    }
    return [valuesDictionary autorelease];
}

- (NSArray*)dataStructuresFromManagedObjects:(NSArray*)managedObjects {

    NSMutableArray *dataArray = [[NSArray alloc] init];
    for (NSManagedObject *managedObject in managedObjects) {
        [dataArray addObject:[self dataStructureFromManagedObject:managedObject]];
    }
    return [dataArray autorelease];
}


//method to call for obtaining JSON structure - i.e. public interface to this class
- (NSString*)jsonStructureFromManagedObjects:(NSArray*)managedObjects {
    NSLog(@"-------------> just before running the recursive method");
    NSArray *objectsArray = [self dataStructuresFromManagedObjects:managedObjects];
    NSLog(@"-------------> just before running the serialiser");
    NSString *jsonString = [[CJSONSerializer serializer] serializeArray:objectsArray];
    return jsonString;
}

- (NSManagedObject*)managedObjectFromStructure:(NSDictionary*)structureDictionary withManagedObjectContext:(NSManagedObjectContext*)moc {

    NSString *objectName = [structureDictionary objectForKey:@"ManagedObjectName"];
    NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:objectName inManagedObjectContext:moc];
    [managedObject setValuesForKeysWithDictionary:structureDictionary];

    for (NSString *relationshipName in [[[managedObject entity] relationshipsByName] allKeys]) {
        NSRelationshipDescription *description = [[[managedObject entity]relationshipsByName] objectForKey:relationshipName];
        if (![description isToMany]) {
            NSDictionary *childStructureDictionary = [structureDictionary objectForKey:relationshipName];
            NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc];
            [managedObject setValue:childObject forKey:relationshipName];
            continue;
        }
        NSMutableSet *relationshipSet = [managedObject mutableSetValueForKey:relationshipName];
        NSArray *relationshipArray = [structureDictionary objectForKey:relationshipName];
        for (NSDictionary *childStructureDictionary in relationshipArray) {
            NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc];
            [relationshipSet addObject:childObject];
        }
    }
    return managedObject;
}

//method to call for obtaining managed objects from JSON structure - i.e. public interface to this class
- (NSArray*)managedObjectsFromJSONStructure:(NSString *)json withManagedObjectContext:(NSManagedObjectContext*)moc {

    NSError *error = nil;
    NSArray *structureArray = [[CJSONDeserializer deserializer] 
                               deserializeAsArray:[json dataUsingEncoding:NSUTF32BigEndianStringEncoding] 
                               error:&error];

    NSAssert2(error == nil, @"Failed to deserialize\n%@\n%@", [error localizedDescription], json);
    NSMutableArray *objectArray = [[NSMutableArray alloc] init];

    for (NSDictionary *structureDictionary in structureArray) {
        [objectArray addObject:[self managedObjectFromStructure:structureDictionary withManagedObjectContext:moc]];
    }
    return [objectArray autorelease];
}


@end

当你在原始帖子上发表评论时,我回答了这个问题。您需要对递归的工作方式进行一些更改,以便它不会进入循环。有很多方法可以做到这一点

例如,您可以更改调用以获取所有关系,改为在
NSManagedObject
子类中调用仅返回下游关系的方法。在该设计中,ObjectA将返回ObjectB关系,但ObjectB不会返回任何关系(或与ObjectC的关系,等等)。这将为递归创建一个树状层次结构

遵循代码的逻辑。它处理您交给它的一个或多个对象,然后遍历与第一组对象关联的每个对象。从你的帖子中,你已经表明你明白这是一个循环。现在,您需要在代码中用逻辑中断该循环,以将其从循环更改为树

此外,我意识到这听起来像是在给我的书拉皮条,我在书中关于导出食谱的多线程章节中解释了如何避免这种循环

更新NSDate
这听起来像是您正在使用的JSON解析器中的一个bug,因为它应该能够处理日期。但是,您的解决方案是可行的,除非您需要在PITA的两侧进行转换。我会查看您的解析器,看看它为什么不能正确地翻译日期,因为这是一个相当大的遗漏

我只想指出一个小的输入错误,它导致了代码崩溃,希望这能节省您几分钟的时间

- (NSArray*)dataStructuresFromManagedObjects:(NSArray*)managedObjects {

    NSMutableArray *dataArray = [[NSArray alloc] init];
    for (NSManagedObject *managedObject in managedObjects) {
        [dataArray addObject:[self dataStructureFromManagedObject:managedObject]];
    }
    return [dataArray autorelease];
}
NSMutableArray*dataArray=[[NSArray alloc]init];//这应该是NSMutableArray

实际上应该是NSMutableArray*dataArray=[[NSMutableArray alloc]init]

仅此而已


谢谢你

谢谢你的回复。我想我已经设法解决了无休止的递归问题,但代码现在抛出了一个异常,似乎表明NSDate属性无法序列化(即,由于未捕获的异常“NSGenericeException”终止应用程序,原因:“cannot serialized data of type”\uu NSCFDate“”)是这样吗?如果是的话,有什么办法可以解决这个问题吗?我已经买了你的书,并将努力读得更详细。再次感谢你迄今为止的帮助。我是Objective-C初学者,正在尝试在这方面取得一些进展。通过将[date-timeIntervalSince1970]返回的值存储为NSNumber,我解决了上述问题。我会看看你在书中提到的部分。