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...

もう 1 つの方法は、実行ループで操作を遅らせることです。

- (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 Rembember がインジケーターをスーパービューに追加します。

それが役に立てば幸い。

于 2012-06-19T08:52:57.920 に答える