Is creating a UIImage streaming line safe?

Does something like this cause thread safe? This is only creating UIImage, without updating the user interface. I can not find documentation about this.

UIImage * hiResImage = [[UIImage alloc] initWithContentsOfFile:path]; 

FYI, I later update the user interface in the main thread, like this ...

 [imageViewForZoom performSelectorOnMainThread:@selector(setImage:) withObject:hiResImage waitUntilDone:NO]; 

What I already know:

  • Starting with iOS4, many UIKit drawing methods have become thread safe. Read from here .
  • I do not need to update the ui in the background thread (for example, no [myImageView setImage:image]; )

EDIT: let's look at a different point of view. “Non-thread safe” means there is a possibility that it could be blocked forever? or simply means that there is no guarantee on launch time / duration of execution. If this is the last case, then there is no problem if we have some "indefinite amount" of delay when loading the image. The user interface is updated in the main thread. Thus, it is still considered OK to create UIImage, at least for non-thread safety.

I know that this is not related to the question, but I just want to point it out, because I'm afraid there will be no clear answer to my original question :)

+4
source share
3 answers

My experience below is not directly related to UIImage initContentsFromFile: but to UIImage imageWithData , but your question is about the security of UIImage threads.

I recently had to debug a problem using [UIImage imageWithData:] , which is called from the NSURLConnetionDelegate connectionDidFinishLoading function to load images using multiple background streams. Since the downloaded images are used to update the user interface, I had to use [NSOperationQueue mainQueue] addOperationWithBlock ... below:

 - (void) connection:(URLConnection*)connection didReceiveData:(NSData *) data { [imgData appendData:data]; } - (void) connectionDidFinishLoading:(NSURLConnection*)connection { [NSOperationQueue mainQueue] addOperationWithBlock:^{ UIImage *img = [UIImage imageWithData:imgData]; // more code here to update the UI }]; } 
  • When running on the iOS 7.x simulator, img contains a valid image
  • When running on iOS 7.x (iPod Touch) img always nil

During the debugging session, I noticed that the problem (temporarily) disappeared when the debugger stepped through each statement one line at a time. My theory is that running in debug mode does not put UIImage to handle parallel threads running under imageWithData . Therefore, I believe that UIImage imageWithData (and possibly other similar functions) are not thread safe.

Using the @synchronized block seems to fix the problem

 - (void) connectionDidFinishLoading:(NSURLConnection*)connection { [NSOperationQueue mainQueue] addOperationWithBlock:^{ @synchronized(imgData) { // Run the following in a synchronized block UIImage *img = [UIImage imageWithData:imgData]; } // more code here .... }]; } 
+4
source

Yes. It is a fairly common practice to upload images in the background, mainly if it is a remote file or a lot of images are uploaded. And yes, only update the user interface in the main thread.

EDIT:

Due to some enlightening comments, I will revise my first “Yes” answer to “Based on experience and my assessment that there will not be a viable alternative to UIImage thread safety when it comes to image loading, I think it is reasonable to assume that it is. however, each person is guaranteed their own opinion, and perhaps his or her risk associated with a lack of code is too high here to make assumptions under any circumstances. '

+1
source

According to Apple, the answer is yes, it is safe to create a UIImage from any thread:

Since image objects are immutable, you cannot change their properties after creation. Most image properties are set automatically using metadata in the accompanying image file or image data. The immutable nature of image objects also means that they are safe to create and use from any stream .

https://developer.apple.com/reference/uikit/uiimage

0
source

Source: https://habr.com/ru/post/1438225/


All Articles