2010-10-11 3 views
1

Каков наилучший способ синхронизации источника данных, который часто обновляется из фонового потока с помощью основного потока GUI?Обновление источника данных NSTableView из фонового потока

Должен ли я помещать мьютекс pthread вокруг каждого вызова метода? Мне кажется, это тоже довольно тяжело.

EDIT: Я ищу для решения 10.5

ответ

2

Вы всегда можете обновить модель и таблицу данных на главном потоке. В NSObject есть функции, такие как performSelectorOnMainThread:withObject:waitUntilDone:, что позволяет вам легко выполнять вызов функции в основном потоке. Таким образом, вы можете обновить модель с:

[model performSelectorOnMainThread:@selector(addObject:) withObject:newObject waitUntilDone:YES]; 

, а затем обновите TableView с этим:

[tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 

Все становится сложнее, если вам нужно передать более одного объекта, потому что тогда вам нужно использовать вызовы, но я обнаружил, что эти функции могут использоваться большую часть времени.

+0

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

+0

Предположительно, создание объектов в массиве будет занимать больше всего времени, а не вставлять их в массив. Если вы беспокоитесь о загрузке основного потока, добавляющего объекты по отдельности, вы можете добавить несколько файлов за один раз с помощью addObjectsFromArray :. В противном случае, без использования GCD (который вы не можете, если вы делаете приложение 10.5), вам придется использовать NSLock. –

1

Это на Snow Leopard или вы хотите сохранить совместимость с 10.2+? Если вы настроены на сохранение обратной совместимости, вы можете отбросить код, который применяет обновления к другому методу, и вызвать его с помощью performSelectorOnMainThread:withObject:waitUntilDone:

В качестве альтернативы, если вы предпочитаете играть с новыми игрушками и сохранять свой код более читаемый (т. е. свести количество методов к минимуму), вы можете сделать это в режиме реального времени blocks и Grand Central Dispatch. Что-то вроде следующего может быть достаточно:

// The following line is (presumably) executed in your background thread 
NSMutableArray *newEntries = [self doSomeHeavyLiftingInBackground]; 
dispatch_async(dispatch_get_main_queue(), ^{ 
    /* The following lines are executed in the context of your main 
    thread's run loop. You don't need to mess about with locks as it 
    will not be executed concurrently with UI updates. */ 
    id<NSTableViewDataSource> dataSource = [self getDataSource]; 
    NSMutableArray *dataSourceInnards = [dataSource whyIsThisMethodHere]; 
    [dataSourceInnards addObjectsFromArray:newEntries]; 
    [dataSource tellTableViewToReload]; 
}); 

Это имеет то преимущество, не имея искажать ваш код шаблона пасс-а-одного объекта-к-а-раздельным методом.

+0

Избили до удара на несколько секунд, но, надеюсь, это выделяет несколько альтернатив. :) –

Смежные вопросы