forked from davekeck/EBPrimitives
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EBTwoLevelCache.m
76 lines (59 loc) · 2.35 KB
/
EBTwoLevelCache.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#import "EBTwoLevelCache.h"
#import <EBFoundation/EBFoundation.h>
#import "EBDiskCache.h"
@implementation EBTwoLevelCache
#pragma mark - Creation -
- (instancetype)initWithMemoryCache: (NSCache *)memoryCache diskCache: (EBDiskCache *)diskCache transformer: (NSValueTransformer *)transformer
{
NSParameterAssert(memoryCache);
NSParameterAssert(diskCache);
if (!(self = [super init]))
return nil;
_memoryCache = memoryCache;
_diskCache = diskCache;
_transformer = transformer;
if (!_transformer)
_transformer = [EBBlockValueTransformer newWithForwardBlock: ^(id value)
{
return value;
}];
return self;
}
- (instancetype)init
{
EBRaise(@"%@ cannot be initialized via %@!", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
return nil;
}
#pragma mark - Methods -
- (id <NSObject>)objectForKey: (NSString *)key
{
NSParameterAssert(key);
/* Consult the memory cache for an object for our key. If no object exists, we'll dive down to the disk cache and get its raw data. */
id <NSObject> result = [_memoryCache objectForKey: key];
EBConfirmOrPerform(!result, return result);
/* Get the raw data from the disk cache. If no data exists, then simply return nil. */
NSData *resultData = [_diskCache dataForKey: key];
EBConfirmOrPerform(resultData, return nil);
/* Transform the raw data into an object. */
result = [_transformer transformedValue: resultData];
EBAssertOrRecover(result, return nil);
/* Put our new object in the memory cache and return it. */
[_memoryCache setObject: result forKey: key];
return result;
}
- (void)setObject: (id <NSObject>)object forKey: (NSString *)key
{
NSParameterAssert(object);
NSParameterAssert(key);
/* Put the object in our memory cache. */
[_memoryCache setObject: object forKey: key];
/* If our transformer supports reverse transformation, then convert the object into data and place it in our disk cache. */
if ([[_transformer class] allowsReverseTransformation])
{
NSData *objectData = [_transformer reverseTransformedValue: object];
EBAssertOrRecover(objectData, EBNoOp);
if (objectData)
[_diskCache setData: objectData forKey: key];
}
}
@end