PINCache.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // PINCache is a modified version of TMCache
  2. // Modifications by Garrett Moon
  3. // Copyright (c) 2015 Pinterest. All rights reserved.
  4. #import <Foundation/Foundation.h>
  5. #import "PINDiskCache.h"
  6. #import "PINMemoryCache.h"
  7. NS_ASSUME_NONNULL_BEGIN
  8. @class PINCache;
  9. /**
  10. A callback block which provides only the cache as an argument
  11. */
  12. typedef void (^PINCacheBlock)(PINCache *cache);
  13. /**
  14. A callback block which provides the cache, key and object as arguments
  15. */
  16. typedef void (^PINCacheObjectBlock)(PINCache *cache, NSString *key, id __nullable object);
  17. /**
  18. A callback block which provides a BOOL value as argument
  19. */
  20. typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject);
  21. /**
  22. `PINCache` is a thread safe key/value store designed for persisting temporary objects that are expensive to
  23. reproduce, such as downloaded data or the results of slow processing. It is comprised of two self-similar
  24. stores, one in memory (<PINMemoryCache>) and one on disk (<PINDiskCache>).
  25. `PINCache` itself actually does very little; its main function is providing a front end for a common use case:
  26. a small, fast memory cache that asynchronously persists itself to a large, slow disk cache. When objects are
  27. removed from the memory cache in response to an "apocalyptic" event they remain in the disk cache and are
  28. repopulated in memory the next time they are accessed. `PINCache` also does the tedious work of creating a
  29. dispatch group to wait for both caches to finish their operations without blocking each other.
  30. The parallel caches are accessible as public properties (<memoryCache> and <diskCache>) and can be manipulated
  31. separately if necessary. See the docs for <PINMemoryCache> and <PINDiskCache> for more details.
  32. @warning when using in extension or watch extension, define PIN_APP_EXTENSIONS=1
  33. */
  34. @interface PINCache : NSObject <PINCacheObjectSubscripting>
  35. #pragma mark -
  36. /// @name Core
  37. /**
  38. The name of this cache, used to create the <diskCache> and also appearing in stack traces.
  39. */
  40. @property (readonly) NSString *name;
  41. /**
  42. Synchronously retrieves the total byte count of the <diskCache> on the shared disk queue.
  43. */
  44. @property (readonly) NSUInteger diskByteCount;
  45. /**
  46. The underlying disk cache, see <PINDiskCache> for additional configuration and trimming options.
  47. */
  48. @property (readonly) PINDiskCache *diskCache;
  49. /**
  50. The underlying memory cache, see <PINMemoryCache> for additional configuration and trimming options.
  51. */
  52. @property (readonly) PINMemoryCache *memoryCache;
  53. #pragma mark -
  54. /// @name Initialization
  55. /**
  56. A shared cache.
  57. @result The shared singleton cache instance.
  58. */
  59. + (instancetype)sharedCache;
  60. - (instancetype)init NS_UNAVAILABLE;
  61. /**
  62. Multiple instances with the same name are allowed and can safely access
  63. the same data on disk thanks to the magic of seriality. Also used to create the <diskCache>.
  64. @see name
  65. @param name The name of the cache.
  66. @result A new cache with the specified name.
  67. */
  68. - (instancetype)initWithName:(nonnull NSString *)name;
  69. /**
  70. Multiple instances with the same name are allowed and can safely access
  71. the same data on disk thanks to the magic of seriality. Also used to create the <diskCache>.
  72. @see name
  73. @param name The name of the cache.
  74. @param fileExtension The file extension for files on disk.
  75. @result A new cache with the specified name.
  76. */
  77. - (instancetype)initWithName:(nonnull NSString *)name fileExtension:(nullable NSString *)fileExtension;
  78. /**
  79. Multiple instances with the same name are allowed and can safely access
  80. the same data on disk thanks to the magic of seriality. Also used to create the <diskCache>.
  81. @see name
  82. @param name The name of the cache.
  83. @param rootPath The path of the cache on disk.
  84. @param fileExtension The file extension for files on disk.
  85. @result A new cache with the specified name.
  86. */
  87. - (instancetype)initWithName:(nonnull NSString *)name rootPath:(nonnull NSString *)rootPath fileExtension:(nullable NSString *)fileExtension;
  88. /**
  89. Multiple instances with the same name are allowed and can safely access
  90. the same data on disk thanks to the magic of seriality. Also used to create the <diskCache>.
  91. Initializer allows you to override default NSKeyedArchiver/NSKeyedUnarchiver serialization for <diskCache>.
  92. You must provide both serializer and deserializer, or opt-out to default implementation providing nil values.
  93. @see name
  94. @param name The name of the cache.
  95. @param rootPath The path of the cache on disk.
  96. @param serializer A block used to serialize object before writing to disk. If nil provided, default NSKeyedArchiver serialized will be used.
  97. @param deserializer A block used to deserialize object read from disk. If nil provided, default NSKeyedUnarchiver serialized will be used.
  98. @param fileExtension The file extension for files on disk.
  99. @result A new cache with the specified name.
  100. */
  101. - (instancetype)initWithName:(nonnull NSString *)name rootPath:(nonnull NSString *)rootPath serializer:(nullable PINDiskCacheSerializerBlock)serializer deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer fileExtension:(nullable NSString *)fileExtension NS_DESIGNATED_INITIALIZER;
  102. #pragma mark -
  103. /// @name Asynchronous Methods
  104. /**
  105. This method determines whether an object is present for the given key in the cache. This method returns immediately
  106. and executes the passed block after the object is available, potentially in parallel with other blocks on the
  107. <concurrentQueue>.
  108. @see containsObjectForKey:
  109. @param key The key associated with the object.
  110. @param block A block to be executed concurrently after the containment check happened
  111. */
  112. - (void)containsObjectForKey:(NSString *)key block:(PINCacheObjectContainmentBlock)block;
  113. /**
  114. Retrieves the object for the specified key. This method returns immediately and executes the passed
  115. block after the object is available, potentially in parallel with other blocks on the <concurrentQueue>.
  116. @param key The key associated with the requested object.
  117. @param block A block to be executed concurrently when the object is available.
  118. */
  119. - (void)objectForKey:(NSString *)key block:(PINCacheObjectBlock)block;
  120. /**
  121. Stores an object in the cache for the specified key. This method returns immediately and executes the
  122. passed block after the object has been stored, potentially in parallel with other blocks on the <concurrentQueue>.
  123. @param object An object to store in the cache.
  124. @param key A key to associate with the object. This string will be copied.
  125. @param block A block to be executed concurrently after the object has been stored, or nil.
  126. */
  127. - (void)setObject:(id <NSCoding>)object forKey:(NSString *)key block:(nullable PINCacheObjectBlock)block;
  128. /**
  129. Removes the object for the specified key. This method returns immediately and executes the passed
  130. block after the object has been removed, potentially in parallel with other blocks on the <concurrentQueue>.
  131. @param key The key associated with the object to be removed.
  132. @param block A block to be executed concurrently after the object has been removed, or nil.
  133. */
  134. - (void)removeObjectForKey:(NSString *)key block:(nullable PINCacheObjectBlock)block;
  135. /**
  136. Removes all objects from the cache that have not been used since the specified date. This method returns immediately and
  137. executes the passed block after the cache has been trimmed, potentially in parallel with other blocks on the <concurrentQueue>.
  138. @param date Objects that haven't been accessed since this date are removed from the cache.
  139. @param block A block to be executed concurrently after the cache has been trimmed, or nil.
  140. */
  141. - (void)trimToDate:(NSDate *)date block:(nullable PINCacheBlock)block;
  142. /**
  143. Removes all objects from the cache.This method returns immediately and executes the passed block after the
  144. cache has been cleared, potentially in parallel with other blocks on the <concurrentQueue>.
  145. @param block A block to be executed concurrently after the cache has been cleared, or nil.
  146. */
  147. - (void)removeAllObjects:(nullable PINCacheBlock)block;
  148. #pragma mark -
  149. /// @name Synchronous Methods
  150. /**
  151. This method determines whether an object is present for the given key in the cache.
  152. @see containsObjectForKey:block:
  153. @param key The key associated with the object.
  154. @result YES if an object is present for the given key in the cache, otherwise NO.
  155. */
  156. - (BOOL)containsObjectForKey:(NSString *)key;
  157. /**
  158. Retrieves the object for the specified key. This method blocks the calling thread until the object is available.
  159. Uses a lock to achieve synchronicity on the disk cache.
  160. @see objectForKey:block:
  161. @param key The key associated with the object.
  162. @result The object for the specified key.
  163. */
  164. - (__nullable id)objectForKey:(NSString *)key;
  165. /**
  166. Stores an object in the cache for the specified key. This method blocks the calling thread until the object has been set.
  167. Uses a lock to achieve synchronicity on the disk cache.
  168. @see setObject:forKey:block:
  169. @param object An object to store in the cache.
  170. @param key A key to associate with the object. This string will be copied.
  171. */
  172. - (void)setObject:(id <NSCoding>)object forKey:(NSString *)key;
  173. /**
  174. Removes the object for the specified key. This method blocks the calling thread until the object
  175. has been removed.
  176. Uses a lock to achieve synchronicity on the disk cache.
  177. @param key The key associated with the object to be removed.
  178. */
  179. - (void)removeObjectForKey:(NSString *)key;
  180. /**
  181. Removes all objects from the cache that have not been used since the specified date.
  182. This method blocks the calling thread until the cache has been trimmed.
  183. Uses a lock to achieve synchronicity on the disk cache.
  184. @param date Objects that haven't been accessed since this date are removed from the cache.
  185. */
  186. - (void)trimToDate:(NSDate *)date;
  187. /**
  188. Removes all objects from the cache. This method blocks the calling thread until the cache has been cleared.
  189. Uses a lock to achieve synchronicity on the disk cache.
  190. */
  191. - (void)removeAllObjects;
  192. @end
  193. NS_ASSUME_NONNULL_END