Можно ли создать 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 в главном потоке лучше

показать изображение ниже:

enter image description here


на руководство по рисованию и печати гласит:

важно классы UIKit обычно не являются потокобезопасными. Все операции, связанные с чертежом, должны выполняться в основном потоке приложения.

таким образом, как я понимаю, кажется, что единственная проблема связана с "операциями, связанными с рисованием". Если предположить, что правильный класс выполняет такую операцию только в своем drawRect: метод, то подход вы предлагаете штраф.