If both initWithRequest and sendAsyncRequest are Asynchronous ways of connections then whats the major difference ?
Other than completion Handler and Queue concept in sendAsyncReq what else ?
Which 1 is more advantageous ??
The sendAsynchronousRequest is simpler and easier to use, saving you from implementing NSURLConnectionDataDelegate and NSURLConnectionDelegate methods. But if you need richness of delegate approach (e.g. challenge-based authentication, need cancelable requests, etc.), then sendAsynchronousRequest is not up to the job.
If targeting iOS 7 and later, consider NSURLSession, instead, too. You can enjoy simplicity of block-based networking and still enjoy delegate methods if and when needed. Also requests are always cancelable. It also opens new opportunities (e.g. background sessions that continue operating even if your app is no longer active).
Related
In a job interview, I was asked why I should use blocks and GCD instead of NSURLConnection in order to download files asyncronously. After some research I haven't found a good reason to do that. I have multiple apps where I use just NSURLConnection just fine for multiple simultaneous downloads. Is their question attempting to ascertain whether I'm conforming to whatever is trendy (GCD, blocks) or is there any actual, substantial advantage to doing async fetches in this way?
Thanks.
In iOS 7, you generally should not use block-based methods to download files asynchronously. In order to support background transfers, you must use NSURLSession with delegate methods, and cannot use the block-based methods. Beyond that, I'm not sure what is meant here by "instead of NSURLConnection" in any case.
If they meant sendAsynchronousRequest:queue:completionHandler: (which is NSURLConnection), it's convenient, but much less flexible and powerful than the delegate-based NSURLConnection, so the only answer I would have is "because sometimes it's more convenient, and keeps the code closer together, when you don't need much flexibility."
Unless what they actually mean is the part of GCD that really does this: Dispatch I/O. There are reasons to use that directly (particularly if you're using non-HTTP protocols, or if you're managing an HTTP server rather than a client), but they're rare, and not usually for "downloading files asynchronously." The higher level APIs are preferred in most cases.
If you were doing many, many connections, transferring a ton of data over a very fast network connection, I can perhaps see how NSURLConnection's use the runloop for I/O handling and callbacks might become problematic, if you're scheduling these NSURLConnections on the main runloop. That said, you could just as easily spool up a lower priority background thread with its own runloop to keep those operations off the main thread.
If you didn't need all the extra machinery of NSURLConnection (caching, authentication, etc), dispatch_io* is almost certainly a lower overhead mechanism for handling raw network I/O, but you would really be giving up quite a bit of functionality for what I expect, practically speaking, to be a very marginal performance improvement.
I'm not sure. Mainly because NSURLConnection's sendAsynchronousRequest method has a completion handler built into it which uses a block.
Maybe a trick question? To me, it seems like the interviewer just wanted to see if you could conclude that they both can serve the same function.
Blocks and GCD aren't specifically for downloads, but they can make downloading easier. You would have to use them in conjunction with something that did the downloading (like NSURLConnection).
The advantage of using GCD with an NSURLConnection is that you can package it together nicely and don't have to rely on spread-out delegate methods. You can limit the number of connections easily too as well as pausing and stopping connections.
My "go to" set up for complex networking is to use an NSOperationQueue and NSOperation subclasses to do the work.
Each operation then uses a NSURLConnection and its delegate methods to download the data and then process it.
In a way this is already using GCD through the NSOperationQueue but I can't see a reason to use any other method combining blocks and GCD etc...
Did they give you a "correct" answer?
I'm developing an application which must extract new messages for user from the server. I have implemented this as a timer which fires every 2 seconds and call a selector which is a method that implement HTTP request and server respond processing. So I think it is quite a bad idea to do this in a main thread.I have no experience with multithreading in iOS. So I want to know what fits well for parallelizing of this task: GCD or NSThread?
You should work as far up the API stack as possible. That way you can concentrate on programming functionality and not managing threads. GCD uses threads that the system has gotten going anyway and its much more efficient than managing your own code. Its even better to aim to encapsulate your networking into NSOperations that can then be put on an NSOperationQueue and these will be executed on one or more background threads, whatever the system deems is a good number for the current power status and other things like that.
The benefit of NSOperation over a pure GCD approach is that operations can be cancelled. Once a block is committed to GCD it has to run no matter what.
If you want to encapsulate your HTTP requests in NSOperations you might be interested to know that someone has already done this for you. AFNetworking is one of the most widely regarded iOS networking stacks and uses NSOperations as its base to build on and as such is very easily multi threaded.
A good idea would be to try and encapsulate your parsing code into an NSOperation and then as your network request operations return you can create parsing operation instances and put them on another queue for processing in the background.
I am confused on where to use which multithreading tool in iOS for hitting services and changing UI based on service data,
firstly I got accustomed to using NSURLConnection and its delegates, used didreceiveresponse, didreceivedata etc delegates to achieve the task
secondly I learned and used GCD to hit services and update the UI from within the block code
Now I am learning to use performSelectorInBackground() to do work in background thread
Clearly confused on which tool to use where?
NSURLConnection with delegate calls is "old school" way of receiving data from remote server. Also it's not really comfortable to use with few NSURLConnection instances in a single class (UIViewController or what not). Now it's better to use sendAsynchronousRequest.. method with completion handler. You can also define on which operation queue (main for UI, or other, background one) the completion handler will be run.
GCD is good for different tasks, not only fetching remote resources with initWithContentsOfURL: methods. You can also control what type of queues will receive your blocks (concurrent, serial ,etc.)
performSelectorInBackground: is also "old school" way of performing a method in background thread. If you weren't using ARC, you'd need to setup separate autorelease pool to avoid memory leaks. It also has a limitation of not allowing to accept arbitrary number of parameters to given selector. In this case it's recommended to use dispatch_async.
There are also NSOperationQueue with NSOperation and its subclasses (NSInvocationOperation & NSBlockOperation), where you can run tasks in the background as well as get notifications on main thread about finished tasks. IMHO They are more flexible than GCD in a way that you can create your own subclasses of operations as well as define dependencies between them.
The most important thing is, that you never change UI anyway in another thread except the main thread.
I think, that all points you mentioned use the same technique in the background: GDC. But I'm not sure of that.
Anyway it doesn't matter which tool you should use in terms of threading.
It's rather a question of your purpose. If you wan't to fetch an small image or just few data you can use contentsOfURLin a performSelectorInBackground() or a GDC dispatch block.
If it's about more data and more information like progress or error handling you should stick with *NSURLConnection`.
I suggest using GCD in all cases. Other techniques are still around but mainly for backward compatibility.
GCD is better for 3 reasons (at least):
It's extremely easy to use and the code remains very readable because of the use of blocks
It is lower level than things like NSOperation so it is much faster when you need high performance multi threading
It's lightweight and non-intrusive so your code doesn't have to change substantially when you want to add thread management in the middle of a method.
What is the differance between adding a operation which make a synchronous NSURLConnection request in NSOperationQueue ( or synchronous request from a thread ( not main thread)) AND making a asynchronous request from the main thread ?
Both will not block main thread so UI will remain responsive but is there any advantage of using one over other? I know in later method i can track request progress etc but assume that progress and other HTTP stuff is not important here.
They are very similar. The biggest problem with synchronous requests is that they can't easily be cancelled. Depending on your application, that could be a problem. Imagine you are downloading a big document and the user moves to another screen so you no longer need that information. In our case, I actually chose doing asynchronous NSURLConnections on a secondary NSThread, which may be overkill for some apps. It is more complicated, but it gives us the ability to both cancel requests and to decode the JSON/XML/image data on secondary threads so they don't impact main thread user interactivity.
Asynchronous requests are scheduled on the run loop and setup as a run loop source, triggering the code automatically only when there is data received from the network (as any socket source).
Synchronous requests running on a NSThread monopolizes a thread to monitor the incoming data, which is in general quite overkill.
You can always cancel an NSURLConnection even if it has been executed asynchronously, using the cancel method.
I bet using the new API that allows to send an asynchronous request on an NSOperationQueue (+sendAsynchronousRequest:queue:completionHandler:) uses GCD under the hood and dispatch_source_create, or something similar, so that it behave the same way as when an NSURLConnection is scheduled on the run loop, avoiding using an additional thread (watch the WWDC'12 videos that explains why threads are evil and their usage should be minimized), the difference only being that allows you to use a block to be informed upon completion instead of using the delegate mechanism.
Some years ago I created a class that embedded NSURLConnection asynchronous calls and delegate management into a nice block API (see OHURLLoader on my github) that makes it easier to use (feel free to take a look). I bet the new API that uses NSOperationQueues uses the same principle, still doing asynchronous requests on the runloop but allowing you to use blocks instead of having to implement a delegate.
The historical position was that there's an advantage in power consumption, and therefore battery life, in asynchronous requests — presumably including both the older delegate approach and the new block-based approach.
I am currently thinking about the data-model for my iOS App. The app does only receive Information from a server and therefore, the "model" itself generally does all the web-requests, ...
However, these network requests have to be performed in the background - I mean another task, not the iOS background state - and after the request has finished, the information in the Application has to be updated.
Would it make more sense to write a delegate to inform the controller or could I also use NSNotificationCenter? I think an NSNotification-based solution could make the model more universal, e.g. in a desktop application.
And maybe, I should add: the model (since it saves some session Information) is a singleton, so a regular delegate based method would not work...
I don't think that it would be a good idea to use a separate thread to handle the communication. Apart from being complex, it is not necessary since NSURLConnection/NSURLRequest do allow you to handle communication asynchronously, i.e., without blocking.
In detail, you can create an NSURLRequest executing:
NSURLRequest* yourReq = [NSURLRequest requestWithURL:yourURL];
then create an NSURLConnection with:
NSURLConnection* yourConnection = [NSURLConnection connectionWithRequest:yourReq delegate:yourDelegate];
and start it with:
[yourConnection start];
When the data is ready, one of the methods for your delegate (connectionDidFinishLoading:, or connection:didFailWithError:) will be called so that you can update your UI.
All this without blocking.
An even better alternative to using NSURLConnection/NSURLRequest, is using ASIHTTPRequest, which seems to be more resilient as to memory management and also offers a great caching mechanism.
EDIT: if your concern is that being your model a singleton, you cannot have a delegate, let me suggest that you look further into the matter.
Your model may be a singleton and the delegate to your request may have nothing to do with the model, apart from knowing how to access it (which is pretty trivial being the model a singleton).
This is possible by several mechanisms with NSURLConnection, but if you use ASIHTTPRequest, it will become really easy, because each ASIHTTRequest can have its own delegate.
A delegate solution does work and is recommended. It looks something like:
[[DataLayer sharedInstance] fetchDataWithDelegate:self];
That method can spawn a background thread and respond to the delegate on the main thread.