Easy way to cancel current NSXMLParser parsing operation?
Alright.
Lets say i have a UITextField
where a user can input an url such as:
http://foo.bar/foo/bar.asmx
Now, if the application is fed the right URL, it will respond with an NSData
with a bytesize of around 450-700 depending on the returning values, the values differ between users. The call takes around a second or so, and the NSXMLParser
parses the data within a second aswell.
But whenever we input for example:
http://apple.com/foo/bar.asmx
We recieve an NSData
with a bytesize of around 9700. And the parser parses this data through infinity. And i have no idea how to throw the proper errormessage when the user has made input to an invalid url resulting in the NSXMLParser
parses for infinity.
We tried using this.
in the
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
xmlParser = [[NSXMLParser alloc] initWithData:myData];
[xmlParser setDelegate:self];
[xmlParser shouldResolveExternalEntities:YES];
[xmlParser parse];
[self performSel开发者_JS百科ector:@selector(timeOutMyParser:) withObject:nil afterdelay:15];
[xmlParser release];
[connection release];
[myData release];
}
Now, what happens with this code is that the performSelector is never executed since it's forever running the parsing.
So to summarize:
In order to reduce the number of errors our users can create, we need to stop our current NSXMLParser parser operations if they take to long.
Is there any EASY way to cancel the current parsing operation?
Actually calling [xmlParser parse]
returns a boolean value which will be YES if the parsing succeeded. Returns NO otherwise. So just receive the boolean value.
BOOL parserSucceeded = [xmlParser parse];
While parsing, if you get invalid data in your XML or if you want to stop the parsing upon a condition, you can cancel the parsing by calling
[parser abortParsing];
And you can check for the status and do appropriate actions.
BOOL parserSucceeded = [xmlParser parse];
if (parserSucceeded) {
// Parser Succeeded
} else {
// Parser Failed/Aborted
}
The issue was that the [xmlParser parse]
was blocking the main thread, locking everything.
So instead of
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
xmlParser = [[NSXMLParser alloc] initWithData:myData];
[xmlParser setDelegate:self];
[xmlParser shouldResolveExternalEntities:YES];
[xmlParser parse];
[self performSelector:@selector(timeOutMyParser:) withObject:nil afterdelay:15];
[xmlParser release];
[connection release];
[myData release];
}
i did this.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
xmlParser = [[NSXMLParser alloc]init];
[xmlParser setDelegate:self];
[xmlParser shouldResolveExternalEntities:YES];
[self performSelectorInBackground:@selector(someFunction) withObject:xmlParser];
[xmlParser release];
[connection release];
[myData release];
}
Where someFunction
is something like this.
-(void)someFunction:(NSXMLParser *)parser
{
parser = [[NSXMLParser alloc]initWithData:myData];
[parser setDelegate:self];
[parser parse];
[parser release];
}
精彩评论