#iphone #multithreading #xml-parsing #main
#iPhone #многопоточность #синтаксический анализ xml #программа-точка входа
Вопрос:
У меня есть приложение, в котором я загружаю свои XML-данные через NSXMLParser в UITableView. Все это сработало отлично. Поскольку я хотел добавить ActivityIndicator, я должен поместить свои загружаемые данные в другой поток, чем основной. После того, как я сделал это, XML загружается так же, как и мое приложение, но я ничего не вижу в своей таблице. Когда я нажимаю на другую вкладку моего tabbarcontroller, а затем возвращаюсь к таблице, данные в таблице становятся видимыми. Что происходит не так?
Мой файл:
#import "DAFAppDelegate.h"
#import "RootViewController.h"
#import "XMLParser.h"
@implementation DAFAppDelegate
@synthesize window;
@synthesize navigationController;
@synthesize rootViewController;
@synthesize rootTabController;
@synthesize stages;
(void) showAlert
{
UIAlertView *av = [[[UIAlertView alloc] initWithTitle:@"No Connection" message:@"Could not retrieve data" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
[av show];
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[window addSubview:[rootTabController view]];
[window makeKeyAndVisible];
[NSThread detachNewThreadSelector:@selector(parseXML) toTarget:self withObject:nil];
}
- (void) parseXML
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSURL *url = [[NSURL alloc] initWithString:@"http://web.me.com/ijar/Stages.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
{
NSLog(@"No Errors");
}
else
{
[DAFAppDelegate showAlert];
NSLog(@"Error Error Error!!!");
}
[pool release];
}
- (void)dealloc
{
[navigationController release];
[rootViewController release];
[rootTabController release];
[window release];
[stages release];
[super dealloc];
}
@end
Ответ №1:
Вы вызывали reloadData
в своем табличном представлении? Также вы должны отправить сообщение в табличное представление с помощью -performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
.
Вы должны отправить эти сообщения, если ваш анализатор прошел успешно.
if (succeed)
{
[myTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}
Возможно, было бы лучше вызвать объект datasource вашего табличного представления, чтобы обновить его хранилище данных, а затем оттуда сообщить табличному представлению обновить его данные.
Комментарии:
1. Нет, куда я должен поместить эти reloadData и -выполнить selectoronmainthread:(SEL)aSelector с object:(id)аргументом waitUntilDone:(BOOL)wait? Извините за глупые вопросы. Но я новичок в этом. Начинаю учиться, выполняя задания и читая книги. Любая помощь приветствуется 🙂
2. Теперь я поместил ее в код под сообщением об успешном выполнении синтаксического анализа. и мой метод загрузки данных выглядит следующим образом в моем RootViewController: — (void) UpdateTable: (NSMutableArray *)data { AppDelegate.stages = data; [self.TableView reloadData]; } Теперь мой компилятор выдает ошибку в момент загрузки данных.
3. *** Завершение работы приложения из-за неперехваченного исключения ‘NSInvalidArgumentException’, причина: ‘-[ShadowedTableView UpdateTable:]: нераспознанный селектор, отправленный экземпляру 0x5066e00’
4. Он сообщает вам, что не может найти метод UpdateTable в классе ShadowedTableView.
5. Ах да. Когда я меняю это значение на self.RootViewController (где используется метод UpdateTable), компилятор не выдает ошибки. Но теперь конечный результат все тот же. Данные загружаются, но таблица не отображается. И когда я выбираю другую вкладку и возвращаюсь обратно, данные по-прежнему не отображаются, что отличается от того, когда я менял их с вашими указаниями. Было бы проще, если бы я отправил вам файл моего проекта?