iPhone4 iOS5 безопасно ли обновлять UITableView из фонового селектора?

#objective-c #multithreading #uitableview #ios5 #iphone-4

#objective-c #многопоточность #uitableview #ios5 #iphone-4

Вопрос:

У меня есть UITableView на одном из моих контроллеров просмотра, он обновляется сообщениями журнала из нескольких частей моего приложения асинхронно. Все работало нормально, но сегодня я заметил странную ошибку. Примерно через 2 часа весь tableview стал пустым. здесь нет ячеек, нет разделителей строк, только цвет фона.

В этот tableview есть только 2 пути входа.

 NSMutableArray* tableViewCellData;

//in the init method:
 tableViewCellData = [[NSMutableArray alloc]initWithCapacity:15];

 -(void)setContextActionWithTitle:(NSString *)title description:(NSString *)description

        ContextConsoleLogItem* temp = [[ContextConsoleLogItem alloc] initWithDate:[NSDate date] title:title message:description contextAction:kNoContextAction];
        [tableViewCellData insertObject:temp atIndex:0];  
        [contextActionTableView reloadData];
    }

//pretty standard data source management
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return kNumberOfSections;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [tableViewCellData count];
}

//here's how the cell displays itself.
    #pragma mark -
    #pragma mark Cell customization
    -(void)configureCell:(UITableViewCell*) cell atIndexPath:(NSIndexPath*) indexPath
    {
        ContextConsoleLogItem* logItem = [tableViewCellData objectAtIndex:indexPath.row];

        cell.backgroundColor = [UIColor blackColor];
        cell.textLabel.textColor = [UIColor whiteColor];
        cell.textLabel.font = [UIFont systemFontOfSize:9];
        cell.detailTextLabel.textColor = [UIColor whiteColor];
        cell.textLabel.text = logItem.message;
        cell.textLabel.numberOfLines =3;
    }
  

Что может быть причиной того, что tableview «теряет» все свои данные и перестает отвечать на

 -(void)setContextActionWithTitle:(NSString *)title description:(NSString *)description
  

Я подозреваю, что NSMutableArray был выделен с недостаточной емкостью. Он довольно быстро достигнет максимальной емкости. Некоторые сообщения, отправленные с использованием описанного выше метода, поступают от вызовов performSelectorInBackground . Может ли быть так, что один из моих фоновых селекторов достигает емкости NSMutableArray и не может перераспределить его? Но опять же, даже в пустом tableview все равно должны быть ячейки, поэтому я должен иметь возможность видеть разделители строк.

Должен ли я завершать свои вызовы на setContextActionWithTitle:description: с performSelectorOnMainThread помощью?

Может быть, было сделано 2 отдельных вызова для обновления tableview, и каким-то образом они оставили таблицу в несогласованном состоянии? (Здесь я не получаю никаких исключений)

Это очень загадочное поведение, и я был бы признателен за любую помощь в его отладке!

Ответ №1:

Никогда ничего не трогайте в UIKit из фонового потока. Когда-либо.

Комментарии:

1. ха-ха, ясно и по существу, я перепишу свой код, чтобы избежать этого

2. Существует очень ограниченное количество вещей, которые вы можете сделать с объектами UIKit из фоновых потоков. Это хорошо документировано. Если это явно не задокументировано как поддерживаемое, то не делайте этого.

Ответ №2:

Я подозреваю, что NSMutableArray был выделен с недостаточной емкостью

Определенно не тот случай. Как указано в документах:

Изменяемые массивы расширяются по мере необходимости; numItems просто устанавливает начальную емкость объекта.

Джим прав, никогда не касайтесь UIKit из фонового потока.