4

When I read the section on

NSDataReadingOptions
Options for methods used to read NSData objects.

enum {
   NSDataReadingMappedIfSafe = 1UL << 0,
   NSDataReadingUncached = 1UL << 1,
   NSDataReadingMappedAlways = 1UL << 3,
};
typedef NSUInteger NSDataReadingOptions;

It says that

NSDataReadingUncached A hint indicating the file should not be stored in the file-system caches. For data being read once and discarded, this option can improve performance. Available in OS X v10.6 and later. Declared in NSData.h.

So I am assuming that by default these URL requests are cached and there is no need to implement NSURLRequest to cache data if I want to use shared global cache ? Is this understanding correct ?

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
DrBug
  • 2,004
  • 2
  • 20
  • 21

2 Answers2

7

Let me start off by saying that dataWithContentsOfURL:options:error: and its ilk are probably the worst APIs for getting something from network. They are very alluring to developers because they can get a resource from network in a single line of code, but they come with some very pernicious side-effects:

First, they block the thread on which they are called. This means that if you execute this on the main thread (the only thread on which your UI can be updated), then your application will appear frozen to the user. This is a really big 'no no' from a user experience perspective.

Second, you cannot cancel these requests, so even if you put this request on a background thread, it will continue to download even though the data may no longer be useful. For example, if your user arrives on a view controller and you execute this request and the user subsequently decides to hit a back button, that data will continue to download, even though it is no longer relevant.

Bottom line: DO NOT USE THESE APIs.

Please use async networking like NSURLConnection or AFNetworking. These classes were designed to get data efficiently and in a way that doesn't impact the user experience. What's even better is that they handle the specific use case you originally asked: how do I stop it from caching on disk?.

Community
  • 1
  • 1
Wayne Hartman
  • 18,369
  • 7
  • 84
  • 116
  • I am aware of what you stated but it does not answer my question. Also, I am setting these URL calls up on my own operationqueue so blocking is not a problem for me. Also I can control what and when gets cancelled. But ... Do you know if it caches or not ? – DrBug Jul 24 '13 at 13:58
  • @DrBug There is no answer to your question, because the reading options refer solely to reading from the _file system_. This method likely works only by _accident_ for accessing _remote resources_. Whether the response is cached in the URL cache is unspecified - that is, we don't know, and the internal behavior and implementation can change with each new OS version. – CouchDeveloper Jul 25 '13 at 14:47
  • Thanks, I agree. If you can make that an answer, I will accept that and upvote your response :) ! – DrBug Jul 25 '13 at 17:59
4

There is no answer to your specific question which refer to the caches managed by the URL loading system.

The reading options in method dataWithContentsOfFile:options:error: refer solely to reading from the file system (please consult to the official documentation of NSDataReadingOptions).

Unfortunately, the documentation gives no hint about the behavior when reading from remote resources. Whether the response is cached in the URL cache is unspecified - that is, we don't know, and the internal behavior and implementation can change with each new OS version.

IMHO, we should generally avoid to use the "convenient methods" to read from remote resources. It appears, these methods work only by "accident" when accessing remote resources. So, I strongly agree with @Wayne Hartman ;)

CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67
  • It's certainly no accident; they very deliberately do work. But it is virtually always best to perform IO asynchronously, which is exactly what `NSURLConnection` is designed for – Mike Abdullah Jul 31 '13 at 14:46
  • 1
    Yes, they "work" sometimes - but the behavior is not documented. These methods should be deprecated for use with remote URLs. Otherwise, we shall assume if option `NSDataReadingMappedAlways` is set, the method will write to a temporary file and delivers data to the mapped file, right? When will the temporary file be deleted? Where is it written to? What is the timeout value for the request. Is HTTP used at all? What is the Accept header? Does it perform authentication? Sorry, this is simply the wrong method for this task. – CouchDeveloper Jul 31 '13 at 15:13
  • The header for `NSDataReadingMappedAlways` says "Hint to map the file in *if possible*" (emphasis mine). A perfectly reasonable interpretation of that says remote URLs will simply not be mapped. I wholeheartedly agree that these methods should generally be avoided for working with remote URLs, but it is perfectly reasonable to expect them to support anything the URL Loading System does. – Mike Abdullah Aug 01 '13 at 16:56