Можно ли создать 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];
}
Спасибо заранее.
Ответы
Ответ 1
От UIView:
Рекомендации по Threading
Манипуляции к вашим приложениям пользовательский интерфейс должен присутствовать в основном потоке. Таким образом, вы всегда должны вызывать методы класса UIView из кода, запущенного в основном потоке вашего приложения. Единственный раз, когда это может быть не обязательно, необходимо создать объект представления, но все другие манипуляции должны произойти в основном потоке.
Вызов initWithFrame:
явно не является потокобезопасным. Вызов setText:
, скорее всего, не является потокобезопасным, попадая под предложение "манипуляции". Они, конечно же, не обещают быть потокобезопасными.
Сделайте свою работу, чтобы выяснить данные в фоновом потоке. Затем создайте свои представления в основном потоке. Если существует огромное количество представлений, вы можете попробовать разделить работу, используя несколько вызовов dispatch_async()
в основную очередь. Это может позволить пользовательскому интерфейсу реагировать; Я не очень много экспериментировал с ним.
Вы также можете рассмотреть возможность перехода с UIView
на CALayer
, где это возможно. Большинство CALayer
могут выполняться в фоновом режиме. Если у вас есть огромное количество просмотров, это, вероятно, неэффективно. Если это просто то, что для вычисления данных для просмотров требуется много времени, это предполагает, что вы не должным образом разделяете информацию о модели и представлении. Класс Model должен вычислять все необходимое независимо от создания представлений.
Ответ 2
Я использую Xcode Version 9.0 beta 3 (9M174d), получая предупреждение.
[UView init] должен вызываться только из основного потока
Итак, я думаю, вам лучше создать пользовательский интерфейс в главном потоке
Покажите снимок ниже:
![введите описание изображения здесь]()
Ответ 3
Руководство по рисованию и печати:
Важно. Классы UIKit, как правило, не являются потокобезопасными. Все связанные с рисованием операции должны выполняться в основном приложении вашего приложения.
Таким образом, как я понимаю, кажется, что единственная проблема связана с "связанными с рисованием операциями". Если предположить, что правильный класс выполняет такую операцию только в своем методе drawRect:
, то подход, который вы предлагаете, должен быть хорошим.