1

我正在尝试在另一个线程上下载一些 XML,并对其进行解析。

我释放“控制器”,然后在 NSOperationQueue 上调用 cancelAllOperations。并在尝试将 nSXMLParser 的委托设置为 nil 的 NSoperation 上实现方法“取消”。

但是大约一秒钟后,NSXMLParser 仍然活着并且正在踢并调用它的委托(现在不再存在)上的方法,从而导致崩溃。

我只是不明白,我做错了什么?

#import "LoadXMLTheadedController.h"
#import "LoadXMLThreaded.h"


 @implementation LoadXMLTheadedController


- (id)initWithURLString:(NSString *)newString
{self = [super init]; 

queue  = [[NSOperationQueue alloc] init];

loadXMLThreaded = [[LoadXMLThreaded alloc] initWithDelegate:self andXMLURLString:newString];

[queue addOperation:loadXMLThreaded];

return self;
}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName     namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    NSLog(@" do some parsing.. ");

}


- (void)dealloc {

[[NSNotificationCenter defaultCenter] removeObserver:self];
[queue cancelAllOperations];

[loadXMLThreaded release];
[queue release];
[super dealloc];
}
@end

//----------------------------------------------------------------//

#import "LoadXMLThreaded.h"

@implementation LoadXMLThreaded



- (id)initWithDelegate:(id)newDelegate andXMLURLString:(NSString *)newString
{
[super init];

delegate = newDelegate;
url = [[NSURL URLWithString:newString]retain];

return self;
}


- (void)cancel{

nSXMLParser.delegate = nil;
[nSXMLParser abortParsing];

 }
- (void)main {


nSXMLParser = [[NSXMLParser alloc]initWithContentsOfURL:url];
nSXMLParser.delegate = delegate;
[nSXMLParser parse];    
}

 - (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
nSXMLParser.delegate = nil;
[nSXMLParser abortParsing];
[nSXMLParser release];
[url release];
[super dealloc];
}
@end
4

3 回答 3

0

我知道我参加这个聚会迟到了,但我想我会投入 2 美分。离开@futureelite7,你永远不应该重写该cancel方法。

相反,在整个 NSOperation 的子类中,您应该定期验证操作是否通过 using 取消isCancelled并采取相应措施。在这种情况下,我们想要中止解析。

例如,在您的 NSXMLParser 委托方法之后,将其作为方法中的第一行:

// make your parser an ivar
if ([self isCancelled]) [operationParser abortParsing];

此外,我建议将您的 NSOperation 设置为 NSXMLParser 委托,因此所有解析都封装在您的 NSOperation 子类中。

最后,仅供参考,中止解析将导致代码错误NSXMLParserDelegateAbortedParseError。请在错误处理期间注意它。

于 2011-09-22T17:24:23.857 回答
0

NSOperation 的取消方法只是设置一个标志。它不会强制停止 NSOperation 本身。用户负责实现必要的代码以停止当前正在运行的任何内容。

您需要定期检查是否设置了取消标志,然后自己在 NSXMLParser 上调用 abort。

于 2010-12-07T06:23:25.867 回答
-1

苹果的文档:

中止解析

停止解析器对象。

- (void)abortParsing

讨论

如果您调用此方法,则通知委托(如果它实现 parser:parseErrorOccurred:)已取消解析操作。

我只是猜测。通常在 Objective-C 中发送一个方法到nil不是问题。但也许NSXMLParser在内部做一些花哨的事情。

关于您的代码的一般说明

  • 学习如何正确编写init方法
  • 您不必将对象的委托设置为nil无论如何都会被释放。
于 2009-11-03T12:54:13.877 回答