If you are an iOS developer using Mattt Thompson’s ‘delightful networking framework’ AFNetworking (and
if you aren’t, what are you waiting for?), perhaps you have been been curious or confused about the caching mechanism employed and how you can tweak it to your advantage.
AFNetworking actually
takes advantage of 2 separate caching mechanisms:
AFImagecache: a memory-only image
cache private to AFNetworking,
subclassed off of NSCache
NSURLCache: NSURLConnection‘s default
URL caching mechanism, used to store NSURLResponse objects
: an in-memory cache by default, configurable as an on-disk
persistent cache
In order to understand how each caching system works, let’s look at how they are defined:
AFImageCache is
a part of the UIImageView+AFNetworking category.
It is a subclass of NSCache,
storing UIImage objects
with a URL string as its key (obtained from an input NSURLRequestobject).
AFImageCache definition:
AFImageCache is
a private implementation of NSCache.
There is no customization that you can do outside of editing the implementation in the the UIImageView+AFNetworking category,
directly. It stores all accessed UIImage objects
into its NSCache. The NSCache controls
when the UIImage objects
are released. If you wish to observe when images are released, you can implement NSCacheDelegate’s cache:willEvictObject method.
Edit (03.14.14) : Mattt Thompson has gratiously informed me that as of AFNetworking 2.1, AFImageCache is
configurable. There is now a public setSharedImageCache method.
Here’s the full AFN 2.2.1 UIImageView+AFNetworking
specification.
Since AFNetworking uses NSURLConnection,
it takes advantage of its native caching mechanism,NSURLCache. NSURLCache caches NSURLResponse objects
returned by server calls via NSURLConnection.
An NSURLCache sharedCache is
enabled by default and will be used by any NSURLConnectionobjects
fetching URL contents for you.
Unfortunately, it has a tendency to hog memory and does not write to disk in its default configuration. To tame the beast and potentially add some persistance, you can simply declare a shared NSURLCache in
your app delegate like so:
Here we declare a shared NSURLCache with
2mb of memory and 100mb of disk space
NSURLCache will
respect the caching policy (NSURLRequestCachePolicy)
of each NSURLRequestobject.
The policies are defined as follows :
NSURLRequestUseProtocolCachePolicy: specifies that the caching logic defined in the protocol implementation, if any, is used for a particular URL load request. This is the default policy for URL load requests
NSURLRequestReloadIgnoringLocalCacheData: ignore the local cache, reload from source
NSURLRequestReloadIgnoringLocalAndRemoteCacheData: ignore local & remote caches, reload from source
NSURLRequestReturnCacheDataElseLoad: load from cache, else go to source.
NSURLRequestReturnCacheDataDontLoad: offline mode, load cache data regardless of expiration, do not go to source
NSURLRequestReloadRevalidatingCacheData: existing cache data may be used provided the origin source confirms its validity, otherwise the URL is loaded from the origin source.
Either the Cache-Control header
or the Expires header
MUST be in the HTTP response header from the server in order for the client to cache it (with the existence of the Cache-Controlheader
taking precedence over the Expires header).
This is a huge gotcha to watch out for. Cache
Control can have parameters defined such as max-age (how
long to cache before updating response), public / private access, or no-cache (don’t
cache response). Here is
a good introduction to HTTP cache headers.
If you would like to bypass the requirement for a Cache-Control HTTP
header and want to define your own rules for writing and reading the NSURLCache given
an NSURLResponse object,
you can subclass NSURLCache.
Here is an example that uses a CACHE_EXPIRES value
to judge how long to hold on to the cached response before going back to the source:
(Thanks to Mattt Thompson for the feedback and code edits!)
Now that you have your NSURLCache subclass,
don’t forget to initialize it in your AppDelegate in order to use it :
The -connection:willCacheResponse delegate
is a place to intercept and edit the NSURLCachedResponse object
created by NSURLConnection before
it is cached. In order to edit theNSURLCachedResponse,
return an edited mutable copy as follows (code from NSHipster blog):
Don’t want to use the NSURLCache?
Not Impressed? That’s okay. To disable the NSURLCache,
simply zero out memory and disk space in the shared NSURLCache definition
in your appDelegate:
I wanted to write this blog post for the benefit of the iOS community, to summarize all of the information I found dealing with caching releated to AFNetworking.
We had an internal app loading a lot of images that had some memory issues and performance problems. I was tasked with trying to diagnose the caching behavior of the app. During this exercise, I discovered the information on this post through scouring the
web and doing plenty of debugging and logging. It is my hope that this post summarizes my findings and provides an opportunity for others withAFNetworking experience
to add additional information. I hope that you have found this helpful.
版权声明:本文为博主原创文章,未经博主允许不得转载。
How Does Caching Work in AFNetworking? : AFImageCache & NSUrlCache Explained
原文地址:http://blog.csdn.net/xiaoyangsavvy/article/details/47614291