Re: Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6?
Re: Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6?
- Subject: Re: Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6?
- From: Ken Thomases <email@hidden>
- Date: Sun, 30 Aug 2009 14:12:31 -0500
On Aug 30, 2009, at 1:47 PM, Adam R. Maxwell wrote:
On Aug 30, 2009, at 10:18 AM, Ken Thomases wrote:
On Aug 30, 2009, at 10:29 AM, Steven Degutis wrote:
I either would need to use NSURLConnection in a stand-alone class,
or use it
synchronously inside a non-concurrent NSOperation subclass.
(Please correct
me if I'm wrong!)
As Adam Maxwell said, you can use a non-concurrent operation which
uses the asynchronous NSURLConnection APIs and runs the run loop
itself. Handling cancel may require that you send a message from
whatever thread invoked -cancel to the thread on which your
operation is running, which may be non-trivial.
What messaging between threads is required? My suggestion is to
periodically check [self isCancelled] and run the runloop with a
timeout, and bail out if that's true. You have to do this anyway in
order to support cancellation, since it doesn't stop anything on its
own.
Well, that's polling and is generally discouraged.
While you would have to check [self isCancelled] each time through the
run loop, if you treat cancellation as a message from one thread to
the other then you don't have to set a timeout. Processing the
message from the other thread will cause -[NSRunLoop
runMode:beforeDate:] to return, so you have the opportunity to check
then before looping back around and calling it again.
If you're relying on a timeout, you have a trade off. Either you
check frequently, making a thread waste resources when it should be
idle, or you check infrequently, meaning there's a significant delay
between when you cancel the operation and when it actually finishes.
This, in turn, delays when any dependent operations can start and when
the queue recognizes that it has a slot free to start any independent
operation that may have been queued. Also, if you have a GUI showing
the state of the download, there may be a worrisome delay between when
the user tried to cancel and when it actually stops.
Another approach to consider is to make a concurrent operation
which actually shunts its work to the main thread using -
performSelectorOnMainThread:... So, NSOperationQueue would invoke
-start on whichever thread it likes (you shouldn't rely on it being
or not being anything in particular). -start would perform a
selector on the main thread that creates the NSURLConnection and
starts the download. As a consequence, it will be tied to the main
thread's run loop. As data arrives, NSURLConnection will invoke
your delegate methods on the main thread, too, so they shouldn't
block or do long computations. (If you want to do long
computations with the result of the download, you should queue up a
separate operation for that once the download has completed.) Your
operation class will probably want to respond to -cancel by sending
-cancel to the NSURLConnection; this, too, must be shunted to the
main thread.
That would probably work pretty well, assuming that generating
isExecuting/isFinished KVO notifications on the main thread is okay.
Of course that's OK. The NSOperation[Queue] docs already say that you
have to cope with the KVO notifications being delivered on any thread.
"Because an operation may execute in any thread, any KVO notifications
associated with that operation may similarly occur in any thread."
On what thread would you expect delivery of the KVO notifications from
a non-current operation on the mainQueue, for example?
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden