Easy way to cancel current NSXMLParser parsing ope

2019-08-23 09:37发布

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 performSelector:@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?

2条回答
男人必须洒脱
2楼-- · 2019-08-23 09:55

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];

}
查看更多
ら.Afraid
3楼-- · 2019-08-23 10:16

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
}
查看更多
登录 后发表回答