我正在使用TBXML创建一个xml解析器类。我希望该类加载一个xml doc,遍历它,并返回一个字符串数组来填充表。这应该在后台线程中进行,因此它会阻止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];
}
答案 0 :(得分:2)
像这样,你会得到一个空数组,对吧?这是因为loadObjects
没有阻塞并且在它完成任务之前返回。
现在,您希望您的viewDidLoad
立即返回,以便您的桌子可以显示。因此,在TableViewController
中,您需要一个被调用的回调,并在显示空表后管理更新。标准技术是使用委托。在Parser.h
定义
@protocol ParserProtocol <NSObject>
-(void)parserDidFinishLoading;
@end
@property id<ParserProtocol> delegate;
使用
行完成successBlock
[self.delegate parserDidFinishLoading];
然后使TableViewController符合ParserProtocol
并将Parser添加为属性:
@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
指向array
的现在已修改的Parser
属性。因此,不需要额外的设置。