1

我有一个视图,当我单击一个按钮时,我使用 TBXML 解析器从 XML 文件中获取一些内容。在单击按钮方法中看起来像这样:

// Should be [activityIndicator startAnimating];
NSURL *url = [NSURL URLWithString:@"adress.xml"];
NSData *data = [NSData dataWithContentsOfURL:url];
TBXML *tbxml = [TBXML newTBXMLWithXMLData:data error:nil];
listArray = [NSMutableArray arrayWithObjects:nil];
[self getData:tbxml.rootXMLElement];
// Should be [activityIndicator stopAnimating];

但是activityIndi​​cator不显示......这不是它的实现问题,因为如果我在视图的开头添加它就会看到它......所以我被卡住了。有什么建议吗?

非常感谢

编辑:这是代码:

我的函数,当我单击按钮时调用:

NSURL *url = [NSURL URLWithString:@"adress.xml"];

dispatch_queue_t queue = dispatch_get_global_queue(
                                 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    NSData *data = [NSData dataWithContentsOfURL:url];
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        TBXML *tbxml = [TBXML newTBXMLWithXMLData:data error:nil];
        listArray = [NSMutableArray arrayWithObjects:nil];
        [self getData:tbxml.rootXMLElement];
        [activityIndicator stopAnimating];
    });
});

我的 getData 函数:

- (void) getData : (TBXMLElement *) element
{
    Offre *offre = [[Offre alloc] init];
    do {
        if(!go) if([[TBXML elementName:element] isEqualToString:@"item"]) go = YES;
        if(go)
        {
            if([[TBXML elementName:element] isEqualToString:@"title"]) [offre set_title:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"description"]) [offre set_description:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"pubDate"]) [offre set_pubDate:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"link"]) [offre set_link:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"contract-type"]) [offre set_contractType:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"salary"]) [offre set_salary:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"fn-org"]) [offre set_fnOrg:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"locality"]) [offre set_locality:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"state"]) [offre set_state:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"filiere"]) [offre set_filiere:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"categorie"]) [offre set_categorie:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"statut"]) [offre set_statut:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"country-name"]) [offre set_countryName:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"tag"]) [offre set_tag:[TBXML textForElement:element]];
            if([[TBXML elementName:element] isEqualToString:@"familleMetiers"]) 
            {
                [offre set_familleMetier:[TBXML textForElement:element]];
                [listArray addObject:offre];
                offre = nil;
            }
        }
        if (element->firstChild) [self getData:element->firstChild];
    } while ((element = element->nextSibling));
}

我想知道这是否不是因为函数的递归性。

4

3 回答 3

2

问题是你dataWithContentOfURL需要很长时间。因此,最好在后台执行此操作。你可以这样做:

NSURL *url = [NSURL URLWithString:@"adress.xml"];

dispatch_queue_t queue = dispatch_get_global_queue(
                                 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    NSData *data = [NSData dataWithContentsOfURL:url];
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        TBXML *tbxml = [TBXML newTBXMLWithXMLData:data error:nil];
        listArray = [NSMutableArray arrayWithObjects:nil];
        [self getData:tbxml.rootXMLElement];
        [activityIndicator stopAnimating];
    });
});
于 2012-06-19T08:56:39.010 回答
1
{
    activityview = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [activityview setFrame:CGRectMake(295/2, 375/2, 25, 25)];
    [self.tableView addSubview:activityview];
    [activityview startAnimating];
    NSOperationQueue *queue = [NSOperationQueue new];

    /* Create our NSInvocationOperation to call loadDataWithOperation, passing in nil */
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                            selector:@selector(loadDataWithOperation) object:nil];

    /* Add the operation to the queue */
    [queue addOperation:operation];
    [operation release];
}

-(void)loadDataWithOperation {

    NSURL *url = [NSURL URLWithString:@"adress.xml"];
    NSData *data = [NSData dataWithContentsOfURL:url];
    TBXML *tbxml = [TBXML newTBXMLWithXMLData:data error:nil];
    listArray = [NSMutableArray arrayWithObjects:nil];
    [self getData:tbxml.rootXMLElement];
    [activityview stopAnimating];
}
于 2012-06-19T08:50:03.653 回答
1

这取决于您如何执行 xml 数据的下载和解析。如果您在同一个线程(主要线程)中执行此操作,您将看不到指标。

为避免这种情况,您可以简单地启动指示器,将解析置于后台,完成后,抓住停止指示器。例如使用 GCD,你可以这样做:

// start the indicator

dispatch_queue_t queue = dispatch_queue_create(“com.app.yourtask”,NULL);

dispatch_async(queue,^{
 // your downloading and parsing here

 dispatch_async(dispatch_get_main_queue(),^{

   // stop the indicator
 });
});

// release the queue you create...

另一种方法是在运行循环中延迟操作。

- (void)setUpDataParsing {

  // start the indicator
  [self performSelector:@selector(parseData) withObject:nil afterDelay:0];
}

- (void)parseData {
  // your downloading and parsing here
  // stop the indicator
}

有关更多信息,请查看NSRunLoop Pogo Stick

PS Remember 将指标添加到超级视图。

希望能帮助到你。

于 2012-06-19T08:52:57.920 回答