NSURLConnection synchonous methods from within NSOperation - iphone

Suppose I have multiple NSOperation objects attached to a concurrent queue.
Within these NSOperations, I would call a synchronous method of NSURLConnectionClass, sendSynchronousRequest ... just to not mess up my code with tracing different connections from within a single delegate.
Apple says that sendSynchronousRequest ... is going to automatically create a separate thread with a run loop to trace NSURLConnection delegate messages.
But I already have several additional threads (running inside NSOperation)! So the question is: if I have, say, 10 NSOperation objects and each would call the synchronous method of NSURLConnection, will it produce 10 more additional ("automatically created") threads with run loops or there will be only one for all of them?

Don't worry about the thread that NSURLConnection creates. It is some internal detail. I'm pretty sure it is one global thread shared by all NSURLConnection instances.

Related

what is synchronous and asynchronous in iphone and iPad?

What is synchronous and asynchronous in ios ? I am new in objective c. Which one i should use in my code while i am getting data from server. So please help me.
Thanks in advance.
You should always use asynchronous loading of network requests.
Asynchronous never block the main thread waiting for a network response.
Asynchronous can be either synchronous on a separate thread, or scheduled in the run loop of any thread.
Synchronous blocks main thread until they complete request.
For Demo code or turorial have a look into this link Asynchronous web service client using NSURLConnection and SBJSON
The majority of the time you will go for asynchronous calls for that kind of operations, otherwise you're UI will block because you are using the main thread.
Synchronous, as the name suggests the action will happen in synchronous with the run loop of your application.
To understand it better, say you have to display some data in UITableview after fetching the data from server.Imagine that the request and response from server takes like 3 seconds. When you are fetching this data synchronously from the server, your app will freeze for like 3 seconds between loading tableview and loading the data contents into that tableview
Now if you are sending your request asynchronously, your app won't freeze but it will load the tableview and tableview contents before the server can respond. In other words, your app won't wait for the 3 second of server response time.You have to take necessary delegate actions or blocks actions to check the response and reload the tabledata so that the server response is displayed in tableview.
Which method is better is pure choice what the developer wants and their app should behave but Apple documentation recommends if you are using synchronous calls do not initiate the call from current run loop.
Using asynchronous all threads are execute the operations parallel. So, Never block the main thread waiting for a network response.
Using synchronous all threads are execute the operations one by one. so, should wait until the other thread task done.
Hope It will be suitable.
Quick note based on other answers: dispatch_sync will not block the main thread unless you dispatch to the main thread.
Example:
// Block main thread because the main queue is on it.
dispatch_sync(dispatch_get_main_queue(), ^{ /*do stuff*/ });
// Block background thread.
dispatch_sync(my_work_queue, ^{ /*do stuff*/ });
A Synchronous call(blocking) is one that has to be completed before subsequent calls can be run in the same queue. It is given all of the processor time for that queue until it is complete. This makes it block the queue.
Asynchronous calls can be started in a queue, and then left running on another thread(processor time schedule), owned by that queue, while other calls are started with other threads.
It is very important to use dispatch_async for web calls because it may take time to get a result back and you want other tasks to be able to start in the queue and use it's threads. A common practice is to do web work, like downloading a file, on a custom background queue and then dispatch to the main queue when it is complete, to update the user.
There is more to this and you can read about dispatch queues from Apple, here.

IPhone Development - Main Thread

I am new to iPhone development and I would like to ask a question concerning asynchronous events.
Supposing I have a NSURLConnection and the correspoding delegate methods ie. didReceiveResponse, didFailWithError etc. The methods are called asynchronously when events are fired. Are all methods executed on the main thread? Or does the iOS create separate threads that execute the corresponding method code?
I am facing some random crashes to my app, and I guess that it is a synchronization issue.
The delegate methods of NSURLConnection are executed in the main thread. That is the whole reason behind being asynchronous, no need to have a separate thread.
About the internals, I/O is an inherently asynchronous world, so I also do not think that internally NSURLConnection uses threading. I suppose that it is the OS that manages the communication in a async way, but I am not sure about it.
Anyway, you can be sure that your delegate methods are executed from within the main thread.

Class which handles tasks in thread

I want to make a class which as long as an instance of it is alive, keeps a thread (worker) going and when someone calls a method on it - performTaskWithData:(NSData*)data - then it should process this data in its worker thread.
If additional data is sent while an operation is taking place, then this new data/operation should be queued until the previous processing is done.
I need each instance of this helper class to hold one single worker thread (i.e. the same thread should handle all the processing).
How should I go about doing this?
NSRunLoop? Synchronize access to data block being passed?
Starting in iOS4, Grand Central Dispatch provides by far the simplest and most powerful interface to multithreaded programming.
If you're a registered developer, go watch some of the WWDC videos from 2010 about it. It's intimidating at first, but it's actually really simple and good.
You can do this directly with NSThreads and run loops. However, I would consider using NSOperationQueues, one per instance of your class and set the maximum concurrency of the queue to 1. Your performTaskWithData: would simply add a new instance of a subclass of NSOperation to the queue and that's it.

Using multiple NSURLConnections at the same time - best practices

In my iPhone app, I've been able to use NSURLConnection properly to download data from a URL. I simply set the delegate to my UIView, and make sure that I set up the UIView to answer for the proper delegate functions such as -connection:didReceiveResponse:. However, if I have a number of NSURLConnections (either for a similar type of request, or multiple kinds of requests), it gets messy because the delegate functions, such as didReceiveRequest, don't differentiate between the different requests. The advantage of asynchronous requests is that you are supposed to be able to multiple at once, without blocking the main thread. What's the best practice for how to use multiple NSURLConnection requests at the same time?
I prefer to wrap them in a higher-level object (like ImageDownloader or SomeWebServiceCall) that has all the per-connection/call state information. I usually create a delegate these objects so that the caller gets a more specific callback when the operation has succeeded or failed.
Perhaps look into ASIHTTPRequest, instead of NSURLConnection. ASIHTTPRequest makes a lot of this work trivially easy.
In this case, I'd say NSOperation is your best bet. ASIHTTPRequest is based on NSOperation and allows you to handle each request as an operation, which serves as the delegate for its own NSURLConnection.
You'll have to be careful here though, because by default NSOperations are run on separate threads, but some APIs, like this one, are required to be executed on the main thread. If you inspect the source code to ASIHTTPRequest you'll notice they've got some infrastructure to ensure delegate methods are called on the main thread.
Create an instance variable for each NSURLConnection and NSMutableData. All of your delegate methods have the NSURLConnection object as an argument, so you can match them as such:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (connection == aConnection) {
// Do something with the data for aConnection
} else if (connection == otherConnection) {
// Do something with the data for otherConnection
}
}
This still limits you to one connection per instance variable, so it's not suitable for, for instance, a table view with images on each row that need to be loaded.

Does NSURLConnection block the main thread?

I'm using NSURLConnection in an iPhone application and the interface seems to slow down after sending initWithRequest: to my NSURLConnection instance. I'm not sure if this is occurring because my processing code is taking a long time to handle the response, or if it's because NSURLConnection is blocking the main thread.
Can anyone confirm that NSURLConnection will create the connection and wait for data on a separate thread, and then call its delegate methods on the main thread?
Thanks!
NSURLConnection supports two modes of operation: asynchronous and synchronous. Neither uses separate threads at all. They both use just one thread, that being whatever thread you run them in.
In synchronous mode, NSURLConnection will block whatever thread you run it in. Asynchronous mode uses the run loop to behave (from the developer's perspective) similarly to a background thread but with lower overhead and without any thread-safety issues. If using asynchronous mode, you want to run it in the main thread. It won't block anything.
If your interface is slowing down, that is not consistent with using NSURLConnection synchronously, which would instead cause your interface to stop completely until the request is complete.
If you follow apples example on NSURLConnection the call will be handled in a different thread than the main thread.