3

TBXMLを使用してxmlパーサークラスを作成しています。クラスにxmlドキュメントをロードし、それをトラバースし、文字列の配列を返してテーブルにデータを入力したいと思います。これは、UIをブロックするように、バックグラウンドスレッドで実行する必要があります。xml解析が完了したときにテーブルのデータソース配列が設定されるように、完了ブロックを追加したいと思います。

完了ブロックを実装するにはどうすればよいですか?これが私がこれまでに持っているものです:

Parser.m

- (NSMutableArray *)loadObjects
{
    // Create a success block to be called when the asyn request completes
    TBXMLSuccessBlock successBlock = ^(TBXML *tbxmlDocument) {
        NSLog(@"PROCESSING ASYNC CALLBACK");

        // If TBXML found a root node, process element and iterate all children
        if (tbxmlDocument.rootXMLElement)
            [self traverseElement:tbxmlDocument.rootXMLElement];
    };

    // Create a failure block that gets called if something goes wrong
    TBXMLFailureBlock failureBlock = ^(TBXML *tbxmlDocument, NSError * error) {
        NSLog(@"Error! %@ %@", [error localizedDescription], [error userInfo]);
    };

    // Initialize TBXML with the URL of an XML doc. TBXML asynchronously loads and parses the file.
    tbxml = [[TBXML alloc] initWithURL:[NSURL URLWithString:@"XML_DOC_URL"]
                               success:successBlock
                               failure:failureBlock];
    return self.array;
}


- (void)traverseElement:(TBXMLElement *)element
{    
    do {
        // if the element has child elements, process them
        if (element->firstChild) [self traverseElement:element->firstChild];

        if ([[TBXML elementName:element] isEqualToString:@"item"]) {
            TBXMLElement *title = [TBXML childElementNamed:@"title" parentElement:element];
            NSString *titleString = [TBXML textForElement:title];
            [self.array addObject:titleString];
        };

        // Obtain next sibling element
    } while ((element = element->nextSibling));
}

TableViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    Parser *parser = [[Parser alloc] init];
    self.products = [parser loadObjects]; 
}
4

1 に答える 1

2

このように、空の配列を取得しますよね?これloadObjectsは、がブロックされておらず、タスクを完了する前に戻ってくるためです。

ここで、viewDidLoadテーブルを表示できるように、すぐに戻る必要があります。したがって、ではTableViewController、空のテーブルが表示された後に呼び出されて更新を管理するコールバックが必要です。標準的な手法は、委任を使用することです。定義Parser.hする

@protocol ParserProtocol <NSObject>
-(void)parserDidFinishLoading;
@end

パーサーインターフェイスで追加

@property id<ParserProtocol> delegate;

successBlock行であなたを終える

[self.delegate parserDidFinishLoading];

次に、TableViewControllerをに準拠させParserProtocol、パーサーをプロパティとして追加します。

@property Parser* parser;

TableViewController.mで置換

Parser *parser = [[Parser alloc] init];
self.products = [parser loadObjects]; 

self.parser = [[Parser alloc] init];
self.products = [self.parser loadObjects]; 

と追加

-(void)parserDidFinishLoading{
    [self.tableView reloadData];
}

の変更されたプロパティをself.products指します。したがって、追加のセットアップは必要ありません。arrayParser

頑張って、ピーター。

于 2012-10-06T19:35:11.953 に答える