开发者

How can I disable a button while NSXMLParser runs, then enable it when it completes?

开发者 https://www.devze.com 2022-12-20 04:03 出处:网络
I have a viewController which imports XMLParser.h as the class xmlParser I\'m passing an NSURL object in my viewController to the xmlParser class with the getXML method below

I have a viewController which imports XMLParser.h as the class xmlParser

I'm passing an NSURL object in my viewController to the xmlParser class with the getXML method below

goBu开发者_高级运维tton is the button I tap to call the getXML method below. I disable the button which I tapped to trigger the getXML method, but I'm not sure where to put the code to enable it again once the xmlParser has finished parsing the returned XML.

- (IBAction) getXML {
    goButton.enabled = NO;

    // allocate and initialize the xmlParser 
    xmlParser = [[XMLParser alloc] init];

// then generate the URL we are going to pass to it and call the fetchXML method passing the URL.
    NSURL *xmlurl = [[NSURL alloc] initWithString:@"http://www.mysite.com/myfile.xml"];
    [xmlParser fetchXMLFromURL:xmlurl];

    // release objects
    [xmlurl release];
    [xmlParser release];

}

As per @Squeegy recommendation, I modified my code.

- (IBAction) getXML {
    goButton.enabled = NO;

    xmlParser = [[XMLParser alloc] init];

    [self performSelectorInBackground:@selector(parseInBackground:) withObject:xmlParser];

}

- (void)parseInBackground:(XMLParser*)parser {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSURL *xmlurl = [[NSURL alloc] initWithString:@"http://www.mysite.com/myfile.xml"];

    [parser fetchXMLFromURL:xmlurl];
    [self performSelectorOnMainThread:@selector(didFinishXMLParsing:) withObject:parser];

    [xmlurl release];
    [pool drain];

}

- (void)didFinishXMLParsing:(NSXMLParser*)parser {
    goButton.enabled = YES;
}

Looks to be working until it gets to the line

[self performSelectorOnMainThread:@selector(didFinishXMLParsing:) withObject:parser];

The compiler complains as follows:

2010-02-17 00:22:20.574 XMLApp[2443:521b] *** -[viewController performSelectorOnMainThread:withObject:]: unrecognized selector sent to instance 0x1285a0
2010-02-17 00:22:20.578 XMLApp[2443:521b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[viewController performSelectorOnMainThread:withObject:]: unrecognized selector sent to instance 0x1285a0'
2010-02-17 00:22:20.583 XMLApp[2443:521b] Stack: (
    861696817,
    860329709,
    861700631,
    861203093,
    861166272,
    18715,
    846004025,
    845672609,
    848189713
)


- (IBAction)getXML {
    goButton.enabled = NO;

    xmlParser = [[XMLParser alloc] init];
    NSURL *xmlurl = [[NSURL alloc] initWithString:@"http://www.mysite.com/myfile.xml"];
    [xmlParser fetchXMLFromURL:xmlurl];

    [self performSelectorInBackground:@selector(parseInBackground) withObject:xmlParser];

    [xmlurl release];
    [xmlParser release];
}

- (void)parseInBackground:(NSXMLParser*)parser {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [parser parse];
    [self performSelectorOnMainThread:@selector(didFinishXMLParsing:)
                           withObject:parser
                        waitUntilDone:NO];

    [pool drain];
}

- (void)didFinishXMLParsing:(NSXMLParser*)parser {
    goButton.enabled = YES;
}

The trick is to do the processing on a background thread, which allows the UI to do stuff. When parsing is done, you have to make any UI changes back on the main thread.


When the parser finishes parsing, it will call it's delegate's:

- (void)parserDidEndDocument:(NSXMLParser *)parser

In that method, you can re-enable the button. You should probably do so with a performSelectorInMainThread call, since it involves changing a view.

0

精彩评论

暂无评论...
验证码 换一张
取 消