1

How does NSURLCache determine that it has a cached response for a request? It's not clear to me how equality between two NSURLRequests is defined or how they are hashed.

Honey
  • 24,125
  • 14
  • 123
  • 212
Ben Flynn
  • 17,294
  • 18
  • 92
  • 133

1 Answers1

2

NSURLCache has a property called cachePolicy that can be used to specify the caching behavior to be used. The default is NSURLRequestUseProtocolCachePolicy which means that the caching logic is defined by the protocol implementation (which is HTTP in most cases).

The author of AFNetworking has written an article that explains the differences between each policy, and how the default policy behaves for the HTTP protocol: NSURLCache - NSHipster.

As far as the implementation of the +[NSURLProtocol requestIsCacheEquivalent:toRequest:] method, this is what I was able to get from decompiling it. I can't guarantee it's 100% accurate, but it seems to make sense:

+ (BOOL)requestIsCacheEquivalent:(NSURLRequest*) a toRequest:(NSURLRequest*)b
{
    if(a == b)
    {
        return YES;
    }
    else
    {
        Class classA = [self _protocolClassForRequest:a allowCF:YES];
        Class classB = [self _protocolClassForRequest:b allowCF:YES];

        if(classA != nil && classB != nil)
        {
            if(classA == classB)
            {
                // I assume this is to make sure it's not an abstract comparison
                if([NSURLProtocol self] != self)
                {
                    NSURL *urlA = [[classA canonicalRequestForRequest:a] URL];
                    NSURL *urlB = [[classB canonicalRequestForRequest:b] URL];

                    if([urlA isEqual:urlB])
                    {
                        return YES;
                    }
                }
            }
        }

        return NO;
    }
}
Ryan Pendleton
  • 2,346
  • 16
  • 29
  • Thanks. Specifically I had forgotten about `NSURLProtocol isResponseCachedForRequest:`. I'm still curious, if I don't implement my own protocol, how that method is implemented. Presumably by matching urls? – Ben Flynn Oct 21 '14 at 17:59
  • I couldn't find that method (or even selector) anywhere. where did you find that? – Ryan Pendleton Oct 21 '14 at 20:32
  • Sorry, I think I'm overtired. =) I meant, in NSURLProtocol: `+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b` – Ben Flynn Oct 21 '14 at 21:12
  • @BenFlynn Haha, it's okay. I've decompiled that method and updated my answer to include a rough conversion of it. – Ryan Pendleton Oct 21 '14 at 21:54
  • Awesome! Thanks for that. – Ben Flynn Oct 21 '14 at 22:01
  • Ryan, would you mind taking a look [URLresponse is not retrieved after storing in cache using storeCachedResponse Ask](https://stackoverflow.com/questions/52938033/urlresponse-is-not-retrieved-after-storing-in-cache-using-storecachedresponse). Also just so that I understand what you're doing. Are classA & classB subclasses of `NSURLRequestCachePolicy` and basically if they're not the same then you return NO? And lastly you check for the URL? (Sorry I'm coming from a Swift world). I'm assuming the timeoutInterval has no effect right? – Honey Oct 23 '18 at 21:38