2010-01-13 3 views
1

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

- (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]; 
} 

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

+0

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

+0

Кроме того, помните, что прокрутка табличного представления очень часто вызывает некоторые из методов делегата таблицы: если вы делаете какой-либо тяжелый подъем в этих методах, особенно если этот подъем связан с общим ресурсом, вы вполне можете попытаться недопустимая память доступа. – rpj

+0

Нужно использовать журнал или что-то еще, чтобы продолжить ... также мы даже не можем видеть, как создаются ячейки, которые, скорее всего, будут источником сбоя при прокрутке. –

ответ