NSOperation不会取消NSXMLParser。哪个继续调用委托上的方法导致崩溃

时间:2009-11-03 12:37:41

标签: delegates nsxmlparser nsoperation

我试图在另一个线程上下载一些XML,并解析它。

我释放'controller'然后在NSOperationQueue上调用cancelAllOperations。 并在NSoperation上实现'cancel'方法,尝试将nSXMLParser的委托设置为nil。

但是大约一秒钟后,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

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我知道我参加派对的时间已经很晚了,但是我想我的收入是2美分。离开@ futureelite7,你永远不应该覆盖cancel方法。

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

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

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

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

最后,只是一个fyi,中止解析会导致代码NSXMLParserDelegateAbortedParseError出错。在错误处理期间请注意它。

答案 2 :(得分:-1)

Apple的文档:

  

abortParsing

     

停止解析器对象。

     

- (void)abortParsing

     

讨论

     

如果你调用这个方法,   代表,如果它实现   parser:parseErrorOccurred:,是   通知取消解析   操作

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

关于您的代码的一般评论

  • 了解如何正确撰写init method
  • 您无需将对象的委托设置为将要解除分配的nil