0

我在我的应用程序中使用 xml 解析器。当我运行我的应用程序 10 到 15 次时,它工作正常,但突然它给了我带有上述代码的 bad_access。我的 xml 解析器代码如下:

    -(BOOL)getTheServerStatus:(NSData *)webData
{
    if (webData==NULL) 
    {
        return FALSE;
    }

    parser=[[NSXMLParser alloc]initWithData:webData];
    [parser setDelegate:self];

    [self performSelectorOnMainThread:@selector(parseData:)
                           withObject:webData
                        waitUntilDone:YES];


    if([strVal isEqualToString:@"ok"])
    {
        return TRUE;   
    }

    else 
    {
        return FALSE;

    }

}

- (void)parseData:(NSData *)webData
{
    if(webData==NULL)
    {
        NSLog(@"web data is NULL");
    }
    [parser parse];
}

我正在使用自动引用计数。那么我的代码有什么问题?

4

1 回答 1

0

I assume that getTheServerStatus is getting called on a thread which is NOT the main thread. Yet you do the parsing on the main thread. Is it possible a second thread us clobbering the parser?

EDIT: code changed

So what you should do is NOT block in getTheServerStatus:, but break your problem into two parts. The first is you want to get the status - so you are going to dispatch a block to do that work for you. While that is going on you can throw up a spinner, or just disable some of your UI. That is a design decision of course. When the background thread looking for status is done, it will message you back on the main thread with the result, and you can take whatever action you want then. I just posted an answer to a similar question that has even more code, which you might find helpful.

{ // ivars
    NSXMLParser *parser; // so you can send it abortParsing to cancel the background block
}

-(void)getTheServerStatus:(NSData *)webData
{
    if (webData==nil) // nil is for objects, NULL for pointers
    {
        dispatch_async(dispatch_get_main_queue(), ^{ [self parseResult:NO]; } );
    }

    parser=[[NSXMLParser alloc]initWithData:webData];
    [parser setDelegate:self];

    dispatch_async(dispatch_get_global_queue(0,0), ^
        {
            BOOL ret = [parser parse];
            parser = nil;
            if(ret == YES) {
                    ret = [strVal isEqualToString:@"ok"]; // EDIT
            }
            dispatch_async(dispatch_get_main_queue(), ^{ [self parseResult:ret]; } );
        } );
}

-(void)parserResult:(BOOL)retCode
{
    // now on main thread...
    if(retCode == YES) ....
    else .....
}
于 2012-08-17T13:19:50.447 回答