Browse Source

improved compatibility: #10

ibireme 9 years ago
parent
commit
a369de2c67
5 changed files with 41 additions and 6 deletions
  1. 0 2
      YYCache/YYCache.h
  2. 4 2
      YYCache/YYDiskCache.h
  3. 35 0
      YYCache/YYDiskCache.m
  4. 2 0
      YYCache/YYKVStorage.h
  5. 0 2
      YYCache/YYMemoryCache.m

+ 0 - 2
YYCache/YYCache.h

@@ -55,7 +55,6 @@ FOUNDATION_EXPORT const unsigned char YYCacheVersionString[];
      the app's caches dictionary for disk cache. Once initialized you should not 
      read and write to this directory.
  @result A new cache object, or nil if an error occurs.
- @warning Multiple instances with the same name will make the storage unstable.
  */
 - (instancetype)initWithName:(NSString *)name;
 
@@ -66,7 +65,6 @@ FOUNDATION_EXPORT const unsigned char YYCacheVersionString[];
  @param path  Full path of a directory in which the cache will write data.
      Once initialized you should not read and write to this directory.
  @result A new cache object, or nil if an error occurs.
- @warning Multiple instances with the same path will make the storage unstable.
  */
 - (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
 

+ 4 - 2
YYCache/YYDiskCache.h

@@ -145,7 +145,8 @@
  
  @return A new cache object, or nil if an error occurs.
  
- @warning Multiple instances with the same path will make the storage unstable.
+ @warning If the cache instance for the specified path already exists in memory, 
+     this method will return it directly, instead of creating a new instance.
  */
 - (instancetype)initWithPath:(NSString *)path;
 
@@ -164,7 +165,8 @@
  
  @return A new cache object, or nil if an error occurs.
  
- @warning Multiple instances with the same path will make the storage unstable.
+ @warning If the cache instance for the specified path already exists in memory, 
+     this method will return it directly, instead of creating a new instance.
  */
 - (instancetype)initWithPath:(NSString *)path
              inlineThreshold:(NSUInteger)threshold NS_DESIGNATED_INITIALIZER;

+ 35 - 0
YYCache/YYDiskCache.m

@@ -11,6 +11,7 @@
 
 #import "YYDiskCache.h"
 #import "YYKVStorage.h"
+#import <libkern/OSAtomic.h>
 #import <CommonCrypto/CommonCrypto.h>
 #import <objc/runtime.h>
 #import <time.h>
@@ -45,6 +46,36 @@ static NSString *_YYNSStringMD5(NSString *string) {
             ];
 }
 
+/// weak reference for all instances
+static NSMapTable *_globalInstances;
+static OSSpinLock _globalInstancesLock;
+
+static void _YYDiskCacheInitGlobal() {
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _globalInstancesLock = OS_SPINLOCK_INIT;
+        _globalInstances = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0];
+    });
+}
+
+static YYDiskCache *_YYDiskCacheGetGlobal(NSString *path) {
+    if (path.length == 0) return nil;
+    _YYDiskCacheInitGlobal();
+    OSSpinLockLock(&_globalInstancesLock);
+    id cache = [_globalInstances objectForKey:path];
+    OSSpinLockUnlock(&_globalInstancesLock);
+    return cache;
+}
+
+static void _YYDiskCacheSetGlobal(YYDiskCache *cache) {
+    if (cache.path.length == 0) return;
+    _YYDiskCacheInitGlobal();
+    OSSpinLockLock(&_globalInstancesLock);
+    [_globalInstances setObject:cache forKey:cache.path];
+    OSSpinLockUnlock(&_globalInstancesLock);
+}
+
+
 
 @implementation YYDiskCache {
     YYKVStorage *_kv;
@@ -135,6 +166,9 @@ static NSString *_YYNSStringMD5(NSString *string) {
     self = [super init];
     if (!self) return nil;
     
+    YYDiskCache *globalCache = _YYDiskCacheGetGlobal(path);
+    if (globalCache) return globalCache;
+    
     YYKVStorageType type;
     if (threshold == 0) {
         type = YYKVStorageTypeFile;
@@ -159,6 +193,7 @@ static NSString *_YYNSStringMD5(NSString *string) {
     _autoTrimInterval = 60;
     
     [self _trimRecursively];
+    _YYDiskCacheSetGlobal(self);
     return self;
 }
 

+ 2 - 0
YYCache/YYKVStorage.h

@@ -13,6 +13,7 @@
 
 /**
  YYKVStorageItem is used by `YYKVStorage` to store key-value pair and meta data.
+ Typically, you should not use this class directly.
  */
 @interface YYKVStorageItem : NSObject
 @property (nonatomic, strong) NSString *key;        ///< key
@@ -56,6 +57,7 @@ typedef NS_ENUM(NSUInteger, YYKVStorageType) {
 
 /**
  YYKVStorage is a key-value storage based on sqlite and file system.
+ Typically, you should not use this class directly.
  
  @discussion The designated initializer for YYKVStorage is `initWithPath:type:`. 
  After initialized, a directory is created based on the `path` to hold key-value data.

+ 0 - 2
YYCache/YYMemoryCache.m

@@ -18,8 +18,6 @@
 
 #if __has_include("YYDispatchQueuePool.h")
 #import "YYDispatchQueuePool.h"
-#else
-#import <libkern/OSAtomic.h>
 #endif
 
 #ifdef YYDispatchQueuePool_h