1

別のスレッドで XML をダウンロードして解析しようとしています。

「コントローラー」を解放し、NSOperationQueue で cancelAllOperations を呼び出します。そして、nSXMLParser のデリゲートを nil に設定しようとする NSoperation にメソッド 'cancel' を実装します。

しかし、1 秒ほど後に 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 のサブクラス全体で、操作が取り消されたかどうかを定期的に確認し、isCancelledそれに応じて対処する必要があります。この場合、解析を中止します。

たとえば、NSXMLParser デリゲート メソッドの後に、これをメソッドの最初の行にします。

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

さらに、NSOperation を NSXMLParser デリゲートにすることをお勧めします。これにより、すべての解析が NSOperation サブクラス内にカプセル化されます。

最後に、参考までに、解析を中止すると code でエラーが発生しますNSXMLParserDelegateAbortedParseError。エラー処理中に注意してください。

于 2011-09-22T17:24:23.857 に答える
0

NSOperation の cancel メソッドは、単純にフラグを設定します。NSOperation 自体を強制的に停止するわけではありません。ユーザーは、現在実行中のものを停止するために必要なコードを実装する責任があります。

キャンセルフラグが設定されているかどうかを定期的にチェックしてから、自分で NSXMLParser で中止を呼び出す必要があります。

于 2010-12-07T06:23:25.867 に答える
-1

Apple のドキュメント:

中止解析

パーサー オブジェクトを停止します。

- (void)abortParsing

討論

このメソッドを呼び出すと、デリゲートが を実装している場合、 parser:parseErrorOccurred:解析操作がキャンセルされたことが通知されます。

私はちょうど推測しています。nil通常、Objective-C ではメソッドの送信は問題になりません。しかし、おそらくNSXMLParser内部で何か派手なことをします。

コードに関する一般的な注意事項

  • initメソッドの正しい書き方を学びましょう。
  • nilとにかく解放されるオブジェクトのデリゲートを設定する必要はありません。
于 2009-11-03T12:54:13.877 に答える