Можно ли создать UIView в фоновом потоке? - программирование
Подтвердить что ты не робот

Можно ли создать 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];
}

Спасибо заранее.

4b9b3361

Ответ 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:, то подход, который вы предлагаете, должен быть хорошим.