Сбой прокрутки UITableView - PullRequest
1 голос
/ 13 января 2010

В настоящее время я разрабатываю приложение для iPhone, которое загружает данные из RSS-канала и отображает их в приложении панели вкладок в 2 UITableView, которые мы называем TableViewA и TableViewB. В AppDelegate у нас есть следующий метод:

- (void)getDataWithContext:(NSManagedObjectContext *)context
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSError *parseError = nil;

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    XMLReader *xmlReader = [[[XMLReader alloc] initWithContext:context]autorelease];
    [xmlReader parseXMLFileAtURL:[NSURL URLWithString:@"http://example.com/rss.xml"] parseError:&parseError];
    [pool release];

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

В нашем applicationDidFinishLaunching: метод, который мы вызываем отсоединить новый поток с этим селектором:

if ([self isDataSourceAvailable] == NO) {
    UIAlertView *noConnection = [[[UIAlertView alloc] initWithTitle:@"Connection Unavailable" message:@"The connection to the database is unavailable. The information displayed may be outdated." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    [noConnection show];
}
else{
    [NSThread detachNewThreadSelector:@selector(getDatawithContext:) toTarget:self withObject:context];
}

TableViewControllerA - это UITableViewController

с помощью следующих методов, которые загружают данные и изображения для TableView. Когда завершается поток средства чтения XML сверху, поместив все записи в CoreData, мы получаем уведомление и перезагружаем записи в TableView из CoreData.

TableViewControllerB - это TableViewControllerA, который наследует эти же методы с небольшими изменениями для выбора различных записей из базы данных.

- (IBAction)loadData: (id) sender{
    BroadwayAppDelegate *appDelegate = (BroadwayAppDelegate *) [[UIApplication sharedApplication] delegate];

    checkDate = [NSPredicate predicateWithFormat: @"date <= %@",
                        [NSDate date]];
    if ( [self.showsSegmentedControl selectedSegmentIndex] == UISegmentedControlNoSegment || 
            [self.showsSegmentedControl selectedSegmentIndex] == 0){
        self.listContent = [CoreDataHelper searchObjectsInContext :@"Entry" :self.checkDate :@"title" :YES :appDelegate.managedObjectContext];
    }
    else if ([self.showsSegmentedControl selectedSegmentIndex] == 1){
        self.listContent = [CoreDataHelper searchObjectsInContext :@"Entry" :self.checkDate :@"startDate" :NO :appDelegate.managedObjectContext];
    }
    else if ([self.showsSegmentedControl selectedSegmentIndex] == 2){
        self.listContent = [CoreDataHelper searchObjectsInContext :@"Entry" :self.checkDate :@"endDate" :YES :appDelegate.managedObjectContext];
    }
    else if ([self.showsSegmentedControl selectedSegmentIndex] == 3){
        self.listContent = [CoreDataHelper searchObjectsInContext :@"Entry" :self.checkDate :@"type" :YES :appDelegate.managedObjectContext];
    }

    // create a filtered list that will contain products for the search results table.
    self.filteredContent = [NSMutableArray arrayWithCapacity:[self.listContent count]];

    // restore search settings if they were saved in didReceiveMemoryWarning.
    if (self.savedSearchTerm)
    {
        [self.searchDisplayController setActive:self.searchWasActive];
        [self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex];
        [self.searchDisplayController.searchBar setText:savedSearchTerm];

        self.savedSearchTerm = nil;
    }

    NSError *error;
    [appDelegate.managedObjectContext save:&error];


    [self.tableView reloadData];

}

 - (void)viewDidLoad {
     [super viewDidLoad];
     [self loadData:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadExited) name:@"NSThreadWillExitNotification" object:nil];

     dateFormatter = [[NSDateFormatter alloc]init];
     [dateFormatter setDateStyle: NSDateFormatterMediumStyle];
     self.title = @"Entries";

 }

- (void)threadExited{
    [self loadData:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [NSThread detachNewThreadSelector:@selector(loadImages) toTarget:self withObject:nil];
}
- (void) loadImages{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSArray *coreDataEntries = [CoreDataHelper getObjectsFromContext:@"Entry" :@"title" :NO :appDelegate.managedObjectContext];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    for (Entry *s in coreDataEntries){
        if (s.image == nil) {
            NSString *URLString = [[Entry imageURLFromLink:s.link withExtension:@".jpg"]absoluteString];
            NSURL *imageURL = [NSURL URLWithString:URLString];
            NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
            s.image = [UIImage imageWithData:imageData];
        }
    }
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self.tableView reloadData];
    [pool release];
}

Приложение аварийно завершает работу, если пользователь прокручивает либо табличное представление при перезагрузке данных, либо, возможно, при выходе из программы чтения XML. Почему это происходит и как мы можем это исправить? Мы использовали предоставленные инструменты для проверки утечек памяти и тому подобного, и мы не нашли ничего, имеющего отношение к сбою.

1 Ответ

1 голос
/ 17 января 2010

Запуск в режиме отладки! При сбое приложения нажмите кнопку «Показать отладчик»

alt text
(источник: gyazo.com )

и посмотрите на проблему

или посмотрите видео

...