Is it ok to create a UIView on a background thread?
Asked Answered
M

3

20

I know UIView are not thread safe so i cant add a view on a background thread, to work around this is it ok to create a UIView on a background thread then add it on the main thread?

Note: the reason im not doing this on the main thread is because my actual code is a lot more complex and therefor takes a while to create all the views and fill the values. I dont want the UI to become un-responsive when I do this so im trying to work around this.

for example..

-(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];
}

Thanks in advance.

Maulstick answered 20/6, 2012 at 15:30 Comment(1)
I believe you have it correct. Create it on the background but update the UI on the main.Entanglement
U
19

From UIView:

Threading Considerations

Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.

The call to initWithFrame: is explicitly not thread safe. The call to setText: is likely not thread-safe, falling under the "manipulations" clause. These certainly are not promised to be thread-safe.

Do your work to figure out the data on a background thread. Then create your views on the main thread. If there are a huge number of views, you can try splitting up the work using several dispatch_async() calls onto the main queue. This may let the UI remain responsive; I haven't experimented extensively with it.

You may also want to consider switching from UIView to CALayer where possible. Most CALayer work can be done on background threads. If you have a huge number of views, that's probably inefficient anyway. If it's just that it takes a long time to calculate the data for the views, that suggests you're not properly separating Model and View information. The Model classes should calculate everything needed independently of creating the Views.

Unpractical answered 20/6, 2012 at 15:42 Comment(4)
I'm sorry but could you clarify your answer? The quote from apple specifically says creating a view in the background is okay, but you're saying it's not. Why?Emasculate
@iamataptool probably you can create UIView safely with init method but not with initWithFrame: method?Hedrick
The CALayer tip made my day and week. Thanks a lot!Paraphrase
I disagree that model classes should calculate everything needed for their display in a view. Model classes should restrict their logic only to that which is conceptually relevant to their purpose. If you need logic to alter or transform the model information for display, that should be done by the controller, or by an intermediate view model.Mossman
G
7

I use Xcode Version 9.0 beta 3 (9M174d), receiving a warning.

[UView init] must be called from main thread only

So I think you should create UI in main thread better

Show the picture below :

enter image description here

Gelinas answered 2/8, 2017 at 11:35 Comment(0)
S
-1

The Drawing and Printing Guide states:

Important The UIKit classes are generally not thread safe. All drawing-related operations should be performed on your application’s main thread.

Thus, as I understand this, it seems that the only problem is related to "drawing-related operations". If we assume that a correct class only execute such operation in its drawRect: method, then the approach you suggest should be fine.

Suomi answered 20/6, 2012 at 15:37 Comment(1)
In my case, my app is wakes up via UIApplicationLaunchOptionsLocalNotificationKey , so it is in background. Is it ok, If I perform subview additions when the app is in background? #46585066Faceharden

© 2022 - 2024 — McMap. All rights reserved.