Search code examples
ioscachingnsurlrequestnsurlcachensurlrequestcachepolicy

How does [NSURLCache cachedResponseForRequest:] do its matching?


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.


Solution

  • 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;
        }
    }