2011-01-10 3 views
3

Я тестировал ObjectiveResource (iOS-> Rails bridge). Кажется, что все работает, но библиотека синхронна (или, может быть, нет, но the mailing list that supports it is a mess).Риски использования performSelectorInBackground?

Я задаюсь вопросом, что подводные камни должны просто работает все звонки в performSelectorInBackground ... в небольших тестах, кажется, работает хорошо, но это дело со многими вещами, которые неправильно.

Единственное предостережение, которое я заметил, заключается в том, что вы должны создать пул автономии в методе, выполняемом функцией performSelectorInBackground (а затем вы должны звонить только drain, а не release?).

ответ

8

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

В принципе, безопасность потоков - это то, что вы должны умышленно вставить в свой код или, вероятно, не там. ObjectiveResource не претендует на это, так что я уже нервничаю. Взглянув на источник, похоже, что в основном используется платформа загрузки URL-адресов, которая является потокобезопасной IIRC. Но сам ObjectiveResource-код не является. С первого взгляда все методы класса используют статические переменные, что означает, что все они подвержены условиям гонки, если вы не используете код performSelectorInBackground: несколько раз с использованием кода, который их использует.

Похоже, что ветвь 1.1 на их Github имеет явную поддержку для асинхронного доступа через класс ConnectionManager. Вероятно, лучше использовать это (хотя это, по сути, незапятнанный код, так что остерегайтесь emptor).

+0

Большое спасибо за этот анализ @Chuck. Я думаю, что один из источников проблемы с ObjResource заключается в том, что они делают все с категориями вместо наследования, что приятно (освобождает линию наследования), но ДЕЙСТВИТЕЛЬНО ограничивает в Obj-C, потому что вы не можете иметь переменные в категориях. В любом случае, я думаю, что я мог бы сделать слишком много: для «бизнес-приложения» блокировка, синхронные вызовы, вероятно, просто прекрасны. –

+0

безопасно ли сделать части UIView в фоновом потоке, если я не прикрепляю их к видимому виду, пока есть? –

8

Так вы действительно испытываете какие-либо проблемы? Или вы просто ожидаете их?

Запуск на фоновом потоке не должен вызывать никаких проблем, если вы не попробуете обновить элемент пользовательского интерфейса из того же фонового потока. Обязательно перенаправляйте любые связанные с пользовательским интерфейсом действия в основной поток. Например (псевдо):

- (void)viewWillAppear:(BOOL)animated { 
    [self performSelectorInBackground:@selector(refreshTableView)]; 
    [super viewWillAppear:animated]; 
} 

- (void)refreshTableView { 
    // Where _listOfObjects is used to populate your UITableView 
    @synchronized(self) { 
     self._listOfObjects = [MyDataType findAllRemote]; 
    } 
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 
} 

Примечание также (как указано выше), что если вы меняете значение каких-либо переменных экземпляра на фоне потока, очень важно, чтобы синхронизировать на self, чтобы предотвратить любые другие темы (как основной поток) от доступа к объектам в массиве _listOfObjects во время его обновления или установки. (Или вы можете «получить» неполный объект.)

Я не 100% положительные (комментарии приветствуются), но я считаю, что если вы объявляете _listOfObjects свойства как atomic, вам не нужно беспокоиться о синхронизированный блок. Хотя, вам понадобится синхронизированный блок независимо от объявления @property, если вместо переопределения значения свойства вы вместо этого вносили изменения в один, постоянный экземпляр. (Например, добавление/удаление объектов из статического NSMutableArray.)

+0

Я бы сказал, что я предвосхищаю проблемы. Прямо сейчас, если я сбиваю сервер Rails, ObjectiveResource немедленно возвращается с неправильными ответами (0 для количества записей вместо того, чтобы возвращать ошибку). Я согласен, что, если вы не отрегулируете сам объект, атома должно быть достаточно. О, и вам нужен новый пул авторесурсов для фонового потока. –

+0

Хороший вопрос - я полностью забыл о дополнительном пуле автообновлений. –

+0

мои комментарии к ошибкам были неправильными. У него есть механизм для возврата ошибок. –

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