views:

196

answers:

2

On the iPhone, I would like to do some operations on an image in a separate thread. Rather than dealing with semiphores, locking, etc., I'd like to use the 'One Object, One Thread' method of safely writing this concurrent operation. I'm not sure what is the correct way to copy my object into a new thread so that the object is not accessed in the main thread. Do I use the 'copy' method? If so, do I do this before the thread or inside the thread?

     ...
    -(void)someMethod{
        UIImage *myImage;
        [NSThread detachNewThreadSelector:@selector(getRotatedImage:) toTarget:self withObject:myImage];

    }

    -(void)getRotatedImage:(UIImage *)image{
        ...
        ...
        UIImage *copiedImage = [image copy];
        ...
        ...
    }
+4  A: 

The best thing to do is simply to take the object of interest, pass it into the worker thread and not reference it in the main thread once the worker thread has been started.

enter scope
    create object
    pass the object to the processing thread
    start the processing thread
exist scope
// the object is no longer visible/used/referenced

The most important thing to note: if your main thread is not going to share the object with the worker thread, then it doesn't matter if you create the object on the main thread, create it in the worker thread, copy the object first and then start the thread, or start the thread and copy the object... the important thing is that you DO NOT share the object between the two threads. How you do that is irrelevant.

Update:
Per your comment... if your main thread still needs to access the image at the same time that you are processing it in the getRotatedImage worker thread, then you will have to make the copy before you pass it in the worker thread. If you pass the image in the thread and try to copy it inside the thread, then there is no guarantee that the image will remain unchanged before/while you copy it.

Lirik
The image DOES need to be accessed by other methods in the main thread. The secondary, worker thread just needs the image to perform some calculations and then report those calculations. Does what I've done in my original post successfully keep the main thread and secondary thread from sharing the objects?
GingerBreadMane
@GingerBreadMane I've updated my answer based on your comment. I hope it helps.
Lirik
@GingerBreadMane To answer your question directly: No, given the information you gave me I don't believe that it's safe to copy the image inside the thread. Do it before you pass it in the thread.
Lirik
Thanks for clearing this up for me Lirik. Is [myImage copy]; the appropriate method to use? Does this create a new copy of the object in memory? Also, would the following also create a copy of myImage, or not:UIImage *imageToPassToThread = [[UIImage alloc] init];imageToPassToThread = myImage;
GingerBreadMane
@GingerBreadMane unfortunately my "expertise" ends with the multithreading concepts. I don't have any experience with the IPhone library, so I can't give you any useful advice on how to properly copy the image... but I hope my answer pointed you in the right direction.
Lirik
+3  A: 

Typically, when implementing something like this, you don't create a single thread per object - instead, when you get something for the object to do, you queue it to be handled by a thread pool.

Depending on the number of objects, one thread per object doesn't scale very far.

kyoryu
+1 good point! :)
Lirik
*especially* on the iPhone!
Jason Coco