Можно ли создать UIView в фоновом потоке?
Я знаю, что UIView не являются потокобезопасными, поэтому я не могу добавить представление в фоновый поток, чтобы обойти это, нормально ли создать UIView в фоновом потоке, а затем добавить его в основной поток?
Примечание: причина, по которой я не делаю этого в основном потоке, заключается в том, что мой фактический код намного сложнее, и поэтому требуется некоторое время, чтобы создать все представления и заполнить значения. Я не хочу, чтобы пользовательский интерфейс стал не реагирующим, когда я делаю это, поэтому я пытаюсь обойти это.
для образец..
-(void)addLabel//called on background thread
{
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0,0,40,100)];
[label setText:@"example"]
[self.view performSelector:@selector(addSubview:) onThread:[NSThread mainThread] withObject:example waitUntilDone:YES];
}
спасибо заранее.
3 ответов
С UIView:
Соображения Резьбонарезной
манипуляции с пользовательским интерфейсом вашего приложения должны происходить в основном потоке. Таким образом, вы всегда должны вызывать методы класса UIView из кода, запущенного в главном потоке вашего приложения. Единственное время, когда это может быть не совсем необходимо, - это создание самого объекта представления, но все остальные манипуляции должны происходить в основном потоке.
в вызов initWithFrame:
явно не является потокобезопасным. Вызов setText:
вероятно, не является потокобезопасным, подпадая под предложение "манипуляции". Они, конечно, не обещают быть потокобезопасными.
делать свою работу, чтобы выяснить данные в фоновом потоке. Затем создайте свои представления в основном потоке. Если есть огромное количество просмотров, вы можете попробовать разделить работу, используя несколько dispatch_async()
вызовы в основную очередь. Это может позволить UI оставаться отзывчивым; я не экспериментировал в основном с ним.
вы также можете рассмотреть возможность переключения с UIView
to CALayer
там, где это возможно. Большинство CALayer
работа может быть выполнена в фоновых потоках. Если у вас огромное количество просмотров, это, вероятно, неэффективно в любом случае. Если просто требуется много времени для вычисления данных для представлений, это означает, что вы неправильно разделяете модель и информацию о представлении. Классы моделей должны вычислять все необходимое независимо от создания представлений.
Я использую Xcode Версии 9.0 beta 3 (9M174d), получая предупреждение.
[uview init] должен вызываться только из основного потока
поэтому я думаю, что вы должны создать UI в главном потоке лучше
показать изображение ниже:
на руководство по рисованию и печати гласит:
важно классы UIKit обычно не являются потокобезопасными. Все операции, связанные с чертежом, должны выполняться в основном потоке приложения.
таким образом, как я понимаю, кажется, что единственная проблема связана с "операциями, связанными с рисованием". Если предположить, что правильный класс выполняет такую операцию только в своем drawRect:
метод, то подход вы предлагаете штраф.