gpt4 book ai didi

ios - 使用ARC,系统是否有可能释放正在使用主动解析的内存?

转载 作者:行者123 更新时间:2023-12-01 19:20:22 25 4
gpt4 key购买 nike

我不断收到以下错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString setLinkID:]: unrecognized selector sent to instance 0x6bf37e0'

我正在使用 NSXMLParser 解析 XML 文档,当我遇到标签“链接”时,我正在创建一个自定义 JLink 对象并将解析器委托(delegate)传递给该对象。这种方法工作正常,然后我一定做了一些事情,因为现在每次运行项目时它都会突然产生上述错误。

我一直在努力,但我认为 JLink 对象正在被释放,因此当调用 setLinkID: 方法时,程序会崩溃。有没有其他人遇到过这个问题或知道可能是什么问题?我的代码如下:

导致错误(大部分时间)但有时会发生变化的方法:
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqual:@"linkID"]) {
currentString = [[NSMutableString alloc] init];
[self setLinkID:currentString];
} else if ([elementName isEqual:@"userID"]) {
currentString = [[NSMutableString alloc] init];
[self setUserID:currentString];
} else if ([elementName isEqual:@"url"]) {
currentString = [[NSMutableString alloc] init];
[self setLink:currentString];
} else if ([elementName isEqual:@"displayText"]) {
currentString = [[NSMutableString alloc] init];
[self setText:currentString];
}
}

以及创建 JLink 并使其成为解析器委托(delegate)的方法:
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqual:@"userID"]) {
currentString = [[NSMutableString alloc] init];
[self setUserID:currentString];
[links removeAllObjects];
} //A bunch of other checks
else if ([elementName isEqual:@"link"]) {
JLinks* newLink = [[JLinks alloc] init];
//Setup the parent so that we can regain control of the element
[newLink setParentParserDelegate:self];
[parser setDelegate:newLink];
[[self links] addObject:newLink];
}
}

我正在使用ARC。谢谢

最佳答案

好的,错误说

-[__NSCFString setLinkID:]: unrecognized selector sent to instance 0x6bf37e0

请注意,您以某种方式发送 setLinkID:__NSCFString 实例的消息(基本上是 NSString 的私有(private)子类)。

在您的代码中,您只发送 setLinkID:对自己。因此,不知何故,您的解析器委托(delegate)已被释放,取而代之的是分配了 NSString 的实例。

即使您使用 ARC,您仍然必须了解对象所有权。在这种情况下,NSXMLParser 不会保留对其委托(delegate)的引用,因为这很可能会创建一个保留循环。如果您查看标题或文档,您会看到该属性被定义为弱引用。

我认为正在发生的事情是你设置了解析器,你没有其他对主解析器委托(delegate)的强引用,所以在解析开始后不久,它就被释放了。您需要仔细检查您的代码,并确保您对该主解析器委托(delegate)具有强引用。

如果你这样做,你会遇到问题:
NSXMLParser *parser = ...
[parser setDelegate:[[MyParserDelegate alloc] init]];
// delegate immediately deallocated, no strong references to it
if ([parser parse]) {
MyParserDelegate *delegate = [parser delegate]; // nil or junk at this point

你应该像这样构造你的代码:
NSXMLParser *parser = ...
MyParserDelegate *topLevelDelegate = [[MyParserDelegate alloc] init];
[parser setDelegate:topLevelDelegate];
if ([parser parse]) {
// pull data out of topLevelDelegate

如果您使用交换专用委托(delegate)的模式,topLevelDelegate 需要保持对子委托(delegate)的强引用。如果您有从子级到父级的强引用,则无关紧要,因为子级本身只能从解析器本身访问,而解析器本身不会保留其委托(delegate)。您可能需要两种方式的引用:从 parent 到 child 的强大;从 child 到 parent 的软弱。 (一般来说,这种模式会阻止保留循环。)

哦,回答你的标题问题:是的,ARC 有可能释放你正在使用的内存,如果它只能通过对它的弱引用来访问。但如果你正在使用它,你应该至少有一个强烈的引用。

关于ios - 使用ARC,系统是否有可能释放正在使用主动解析的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10646386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com