我有一个符合NSCoding的自定义对象,因为该对象在终止时应该可写入磁盘。在这个类中,我有各种属性,包含Cocoa对象类型,如NSStrings,NSArrays,NSDictionaries。一个特殊属性是这个:
@property (readwrite, copy) NSArray *artistReleases;
它实际上是一个应该容纳一些NSDictionaries的数组。这些字典是在一个类方法中创建的,该方法负责解析XML文件中的数据。
artist.artistReleases = [NSArray arrayWithArray:releases];
当我尝试使用编码器保存属性时发生错误:
[encoder encodeObject:artistReleases forKey:@"artistReleases"];
我会收到EXC_BAD_ACCESS错误。 NSZombie告诉我
*** -[CFString retain]: message sent to deallocated instance 0xd6f28fe0
......我绝对不知道在哪里寻找这种保留。 malloc_history告诉我:
ALLOC 0xd6f28fe0-0xd6f28fff [size=32]: thread_b0244000 |thread_start |
_pthread_start | __NSThread__main__ | -[NSThread main] |
-[SearchViewController invokeGetArtist:] | +[GetDetails getArtist:summary:theURL:] |
-[CXMLNode stringValue] | +[NSString stringWithUTF8String:] |
-[NSPlaceholderString initWithBytes:length:encoding:] |
CFStringCreateWithBytes | __CFStringCreateImmutableFunnel3 |
_CFRuntimeCreateInstance | GMmalloc_zone_malloc_internal
我不清楚该怎么做。这对我没有任何意义。也许有人可以通过解释malloc历史来指出我在某个方向。
修改
这是填充有问题的属性的部分。为了修复错误,我对一些CXMLNode调用进行了评论,并没有在这里插入。这也意味着似乎没有错误连接到这些对象(直到我尝试访问使用这些方法创建的数据)。顺便说一句,我使用TouchXML进行XPath查询。
NSArray *releaseNodes;
releaseNodes = [root nodesForXPath:@"/pathToReleases" error:nil];
NSMutableArray *releases = [[NSMutableArray alloc] init];
for (CXMLElement *resultElement in releaseNodes) {
if (resultElement != nil) {
NSMutableDictionary *releaseElement = [[NSMutableDictionary alloc] init];
for (int counter = 0; counter < [resultElement childCount]; counter++) {
[releaseElement setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];
}
[releases addObject:releaseElement];
[releaseElement release];
}
}
if ([releases count] == 0)
[releases addObject:[NSMutableDictionary dictionaryWithObject:@"-" forKey:@"title"]];
artist.artistReleases = [NSArray arrayWithArray:releases];
编辑2 我已经缩小了有关财产失去其内容的地方。通过gdb在某个点之后对该属性进行修改会导致错误
Program received signal SIGTRAP, Trace/breakpoint trap.
这一点是为getArtist调用而创建的自动释放池被释放的地方。所有其他属性都很好,但是......所以 - 毕竟错误在于我在第一次编辑中发布的代码部分?
答案 0 :(得分:1)
你的GetDetails课程都是borked或任何正在调用它的人都是borked。具体来说,请参阅分配跟踪的这一部分:
+[GetDetails getArtist:summary:theURL:]
-[CXMLNode stringValue]
如果正确实现,CXMLNode
的{{1}}方法将返回一个自动释放的字符串。需要在其上调用stringValue
(直接或通过属性设置器)。
或者,-retain
方法可能会返回一个保留的字符串?如果是这样,那么它应该在返回之前返回getArtist:summary:theURL:
的结果。
没有看到更多代码,就不可能多说。如果我是下注类型,我怀疑stringValue
是通过引用返回艺术家和摘要?如果是这样,那就是一个强大的愚蠢设计 - 非典型的,甚至 - 但是我敢打赌,来电者假设艺术家和/或摘要在他们不是时保留? ....或者在某个地方有一个额外的自动呼叫?
答案 1 :(得分:0)
找出填充数组的位置。最有可能的是,您已经过度释放了已插入阵列中的一个字符串。当编码器对象尝试访问过度释放的对象时,您会收到错误。