On Jul 23, 2012, at 3:27 AM, Jay Reynolds Freeman wrote:

> If it had never worked properly I would have found and fixed the problem 
> during testing under Snow Leopard.  The problem is that the 10.6 
> implementation worked *exactly* as the documentation specifies, but the 10.7 
> one doesn't.  My code didn't rely on undocumented behavior, it relied 
> precisely on what was documented.  :-)

The documentation doesn’t say that you can block the main thread and still use 
the async API. In fact, it doesn’t even say that it will spawn a new thread at 
all. Of course in practice it would probably use a thread, but strictly going 
by what’s in the documentation, it could theoretically do all the processing in 
tiny little slivers on each iteration of the run loop or on an NSTimer on the 
main thread and still follow that API contract to a tee. Your code is making 
assumptions about what the API is doing, and this is what has come back to bite 
you as the undocumented behavior has changed.

If you think about it, it’s not hard to figure out ways that an asynchronous 
API could fail if the main thread is blocked:

1. If the async API doesn’t use a thread at all, obviously it will fail if the 
thread is blocked.

2. If the async API calls through to some other, lower-level async API, and 
*that* API spawns the thread, and the higher-level async API uses either a 
timer or a notification to detect when the lower-level API finishes, then the 
higher-level API will never detect the process finishing if the main thread is 
blocked.

3. If the async API relies on timers or notifications for anything else, it 
will fail if the main thread is blocked.

4. If the async API uses dispatch_[a]sync, +[NSOperationQueue mainQueue], 
-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:], or something 
similar to use a non-thread-safe API as part of what it does, that won’t happen 
as long as the main thread is blocked.

5. I’ve written async APIs which used the techniques in #4 to set their 
“finished” properties on the main thread at the end, so that the properties can 
be observed via KVC without causing all kinds of non-main-thread calls to UI 
elements. If any API does this, it won’t happen if the main thread is blocked.

Etc., etc. The moral: don’t block the main thread. No Apple asynchronous API is 
guaranteed to work when you do so. Mac users tend to associate the spinning 
beachball with a hung app anyways (note how it’s commonly referred to as the 
beachball of *death*), and if I’m informed correctly, iOS will actually 
automatically kill any app whose main thread is blocked for a certain amount of 
time. Either way, it’s bad mojo.

FWIW, I just built a little test app out of curiosity. In my testing, it works 
exactly the same on Snow Leopard as it does on Lion — the isPlaying property 
stays true forever if the main thread is blocked — so perhaps even the fact 
that it worked for you on 10.6 may have been due to some peculiarity of your 
system. At any rate, it certainly is not something that can be relied upon.

Charles


_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to