views:

434

answers:

1

Imagine that I have a view with some UIKit object as its subview (for example, UIActivityIndicatorView - this doesn't matter). This view also has a selector, called doSomething, which somehow manages UIKit object (in our example it can start or stop indicator view).

I create NSInvocationOperation (from view's code parts) with initWithTarget:self selector:@selector(doSomething) object:nil. Then add it to NSOperationQueue. And all works fine.

How?! It should be a new thread and non-thread-safe UIKit object! Why no error found (and no crash happened)?

+5  A: 

The NSInvocationOperation class is a concrete subclass of NSOperation that implements a non-concurrent operation.

In a non-concurrent operation, the operation’s task is performed synchronously—that is, the operation object does not create a separate thread on which to run the task. Thus, when the start method of a non-concurrent operation is called, the operation executes immediately in the current thread. By the time the start method of such an object returns control to the caller, the task itself is complete.

However, using NSOperationQueue changes this behavior. NSOperationQueue always executes operations concurrently; a non-concurrent operation requires a separate thread in order to execute concurrently, and NSOperationQueue provides this thread.

This means that if you'd execute your NSInvocationOperation directly, you'd be able to access your UIKit object thread-safe(the operation would run o the same thread). In your case, if using a NSOperationQueue, you should schedule the work that uses the UIKit object on the main thread, using NSObject's performSelectorOnMainThread:withObject:waitUntilDone: from your invocation selector.

luvieere
OK, this is a great answer! +1
Jacob Relkin