• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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 09:53:42 -0500

On Aug 30, 2009, at 9:09 AM, Steven Degutis wrote:

Unfortunately, the code I wrote completely broke yesterday when I upgraded
to Snow Leopard (fortunately I hadn't published it yet for that same reason)
and it was narrowed down to the NSOperation subclass not getting any of
NSURLConnection's delegate methods at all. In fact, it seemed that the
object wasn't even getting any messages from
-performSelector:withObject:afterDelay: either, which made me wonder whether
the NSRunLoop of the current NSThread was borked, or if the NSThread itself
was in fact not intact.


Interestingly, it still worked fine when the NSOperation object was run with
-start, it only failed when run by being added to an NSOperationQueue.

In 10.6, NSOperationQueue ignores the -isConcurrent property of the operations and always invokes -start on one of its work threads. This may have contributed to your problem.


That said, I don't think it's ever been a safe assumption that the thread on which either -start or -main is invoked has a run loop that's regularly serviced. If you need the run loop to be run, you should run it yourself. However, you should probably reconsider whether you need to be using a secondary thread, at all. An API which relies on the run loop, like NSURLConnection, is typically already asynchronous (ignoring for the moment the +sendSynchronousRequest:returningResponse:error: method). That is, you can set it up to work on the main thread without blocking it.

A middle ground on 10.6 might be to schedule your operation on + [NSOperationQueue mainQueue]. Then, its -start will be guaranteed to be invoked on the main thread. In that case, you should implement the operation as concurrent. Your -start override should not block while the operation runs to completion. It should set things going and then return immediately. Naturally, this requires the very asynchronous nature of NSURLConnection that I mention above in order to work, which is why wrapping it up as an operation is largely unnecessary. It does let you integrate with other operations via the dependency mechanism, though.


So after more researching of NSOperationQueue's documentation, specifically
under "Avoid Per-Thread Storage" section of the "Operation Queues" guide, it
states the following:


"If an operation queue provides a thread for you, you should consider that
thread to be owned by the queue and not to be touched by your operation.
Specifically, you should never associate any data with a thread that you do
not create yourself or manage. The threads managed by an operation queue
come and go depending on the needs of the system and your application.
Therefore, passing data between operations using per-thread storage is
unreliable and likely to fail."


It seems to be that this exactly describes what is happening when
NSURLConnection is run asynchronously; it tries to use the thread it's
current in and its runloop, even though it created neither, since
NSOperationQueue did.

First of all, am I reading and interpreting this correctly? I could be
mistaken on what this means, as I'm no expert to threads and runloops.

You are basically interpreting it correctly, yes. I would nitpick with your claim that it happens "when NSURLConnection is run asynchronously". It happens when NSURLConnection is run in a thread and that thread's run loop is not guaranteed to be serviced (a.k.a. run).



Secondly, if so, would it be unwise to set up a thread and runloop
specifically for the NSURLConnection itself?

That would also work, but, again, the NSURLConnection is inherently an asynchronous API which can be run on the main thread (and main thread's run loop) without causing trouble. Spinning off your own thread to just sit in its run loop is unnecessary.


The primary benefit NSURLConnection would get from running async inside an NSOperation subclass is that it will be more easily cancelable

I don't understand this claim. NSURLConnection is just about as easily cancelable as is possible. You just invoke its -cancel method. It seems to me to be more easily cancelable than if it is wrapped in an NSOperation subclass.


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


  • Follow-Ups:
    • Re: Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6?
      • From: Steven Degutis <email@hidden>
References: 
 >Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6? (From: Steven Degutis <email@hidden>)

  • Prev by Date: Re: Applying color to template images
  • Next by Date: Framebuffer question
  • Previous by thread: Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6?
  • Next by thread: Re: Async NSURLConnection + Concurrent NSOperation = Not possible under Mac OS X 10.6?
  • Index(es):
    • Date
    • Thread