22

我试图序列化一个包含一组类型(自定义对象)的SearchEntity对象(自定义对象)。NSMutableDictionaryCategoryEntity

1SearchEntity<NSCoding>包含:1 个NSMutableDictionary(参数)参数,其中CategoryEntities<NSCoding>包含仅包含字符串和数字的 X。

在 SearchEntity encodeWithCoder" 的这一行[encoder encodeObject:parameters forKey:kPreviousSearchEntityKey];中,我每次都得到 GDB:Interrupted,没有错误消息、异常等。只是 GDB:Interrupted。

这是实现SearchEntity,参数是NSMutableDictionary

#pragma mark -
#pragma mark NSCoding delegate methods

- (void) encodeWithCoder:(NSCoder*)encoder 
{
    //encode all the values so they can be persisted in NSUserdefaults
    if (parameters) 
        [encoder encodeObject:parameters forKey:kPreviousSearchEntityKey]; //GDB:Interrupted!
}

- (id) initWithCoder:(NSCoder*)decoder 
{
    if (self = [super init]) 
    {
        //decode all values to return an object from NSUserdefaults in the same state as when saved     
        [self setParameters:[decoder decodeObjectForKey:kPreviousSearchEntityKey]];
    }
    return self;
}

还实现了 NSCoding 协议,CategoryEntity如下所示:

- (void) encodeWithCoder:(NSCoder*)encoder 
{
    //encode all the values so they can be persisted in NSUserdefaults
    [encoder encodeObject:ID forKey:kIDKey];
    [encoder encodeObject:text forKey:kTextKey];
    [encoder encodeObject:category forKey:kCategoryKey];
    [encoder encodeObject:categoryIdentifierKey forKey:kCategoryIdentifierKey];
}

- (id) initWithCoder:(NSCoder*)decoder 
{
    if (self = [super init]) {

        //decode all values to return an object from NSUserdefaults in the same state as when saved
        [self setID:[decoder decodeObjectForKey:kIDKey]];
        [self setText:[decoder decodeObjectForKey:kTextKey]];
        [self setCategory:[decoder decodeObjectForKey:kCategoryKey]];
        [self setCategoryIdentifierKey:[decoder decodeObjectForKey:kCategoryIdentifierKey]];
    }
    return self;
}

我尝试从 NSUserDefaults 的包装器中对其进行编码,如下所示:

+ (void) setPreviousSearchParameters:(SearchParameterEntity*) entity
{
    if (entity) 
    {
        //first encode the entity (implements the NSCoding protocol) then save it
        NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:entity];
        [[self defaults] setObject:encodedObject forKey:kPreviousSearchKey];
        [[self defaults] synchronize];      
    }
}

+ (SearchParameterEntity*) getPreviousSearchParameters
{
    //retrieve the encoded NSData object that was saved, decode and return it
    SearchParameterEntity *entity = nil;
    NSData *encodedObject = [[self defaults] objectForKey:kPreviousSearchKey];

    if (encodedObject)
        entity = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];

    return entity;
}

我在想,当我要求序列化 SearchEntity 时,它会开始序列化“参数” mutableDictionary 对象,NSCoder 将对字典中包含的 CategoryEntities 调用“encode”,它们都会以正确的编码对象响应。

但是我只是在控制台底部得到 GDB:Interrupted 。

我该如何调试呢?

我的方法错了吗,我应该在 NSData 中包装所有级别的编码吗?

附言。ResultEntity我对包含的 NSArrays做了完全相同的事情CategoryEntities,它编码没有问题,所以我猜 NSMutableDictionary 是唯一突出的东西。

4

3 回答 3

1

您发布的代码似乎没有错误。我已经对您遗漏的一些细节做出了最好的猜测,并且我从包含您的代码的测试程序中获得了成功的结果,该代码具有足够的样板来表明它正确编码/解码。

(您可以使用:从命令行编译它并使用:gcc -framework foundation test.m -o test运行./test。)

关于您的问题,我该如何调试,我建议采用以下方法:

  • (临时)修改你的代码尽可能简单。例如,您可以将parameters属性更改为普通属性NSString并首先验证它是否正常工作。
  • 慢慢增加复杂性,一次引入一个新属性,直到错误再次出现。最终,您将缩小麻烦数据的来源。

唉,如果这是由于您的应用程序中其他地方的一些管理不善的内存而发生的,那么调试此代码本身可能无法帮助您。尝试(手动)验证您收到的用于编码的每条数据的内存管理是否正确。

如果您已经在使用Core Data,您可以考虑仅在用户默认值中保留对象 ID,并基于此恢复您的对象图。(请参阅:使用 NSCoding 归档 NSManagedObject)。

于 2011-10-03T05:37:25.497 回答
0

我建议你先绕过 NSMutableArray。让 SearchEntity 只包含一个 CategoryEntity,看看它是否有效。

您发布的代码看起来不错,您可能想给我们更详细的上下文。

对于对象编码,此文件可能会有所帮助:DateDetailEntry

于 2011-11-04T03:57:59.983 回答
-1

使用 NSKeyedArchiver 归档对象的问题是您不能对可变对象进行编码。只有NSArrayNSDictionaryNSStringNSDateNSNumberNSData(以及它们的一些子类)的实例可以被序列化

因此,在您的 SearchEntity 方法中,encodeWithCoder:您应该尝试从 NSMutableDictionary 创建 NSDictionary ,然后对不可变的进行编码:

if (parameters) {
    NSDictionary *dict = [NSDictionary dictionaryWithDictionary:parameters];
    [encoder encodeObject:dict forKey:kPreviousSearchEntityKey];
}

同样在initWithCoder:方法中尝试从编码的不可变的创建 NSMutableDictionary :

NSDictionary *dict = [decoder decodeObjectForKey:kPreviousSearchEntityKey];
     [self setParameters:[NSMutableDictionary dictionaryWithDictionary:dict]];

还要检查parameters字典中的所有对象以符合 NSCoding 协议,并确保它们都在其encodeWithCoder:方法中仅编码不可变对象。

希望它能解决问题。

于 2011-09-22T06:50:26.370 回答