From dc1af46fce7058660b435f6a51a5f379d7365540 Mon Sep 17 00:00:00 2001 From: Jacob Jennings Date: Fri, 30 Nov 2012 13:33:29 -0800 Subject: [PATCH 1/3] If the result image is nil, do not attempt to insert it in the cache. --- MSCachedAsyncViewDrawing.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MSCachedAsyncViewDrawing.m b/MSCachedAsyncViewDrawing.m index 9724841..db29db9 100644 --- a/MSCachedAsyncViewDrawing.m +++ b/MSCachedAsyncViewDrawing.m @@ -110,7 +110,7 @@ - (void)drawViewWithCacheKey:(NSString *)cacheKey } UIGraphicsEndImageContext(); - [self.cache setObject:resultImage forKey:cacheKey]; + if (resultImage) [self.cache setObject:resultImage forKey:cacheKey]; if (waitUntilDone) { From f9be0bfb0d689d27f81d83c409fc635910bbd4ec Mon Sep 17 00:00:00 2001 From: Jacob Jennings Date: Wed, 5 Dec 2012 17:36:53 -0800 Subject: [PATCH 2/3] Keep track of in-progress tasks to avoid duplication of effort. Also, avoid inserting nil image into cache. A nil image can result from someone sending CGSizeZero to the method. I think calling completion with the nil image without crashing is a good expected result for that case. --- MSCachedAsyncViewDrawing.m | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/MSCachedAsyncViewDrawing.m b/MSCachedAsyncViewDrawing.m index db29db9..34985e8 100644 --- a/MSCachedAsyncViewDrawing.m +++ b/MSCachedAsyncViewDrawing.m @@ -23,6 +23,7 @@ @interface MSCachedAsyncViewDrawing () @property (nonatomic, strong) NSCache *cache; +@property (nonatomic, strong) NSMutableDictionary *inProgessKeyToCompletionBlocksDictionary; @property (nonatomic, MS_dispatch_queue_t_property_qualifier) dispatch_queue_t dispatchQueue; @@ -48,6 +49,9 @@ - (id)init { self.cache = [[NSCache alloc] init]; self.cache.name = @"com.mindsnacks.view_drawing.cache"; + + self.inProgessKeyToCompletionBlocksDictionary = [[NSMutableDictionary alloc] init]; + self.dispatchQueue = dispatch_queue_create("com.mindsnacks.view_drawing.queue", DISPATCH_QUEUE_CONCURRENT); } @@ -81,6 +85,19 @@ - (void)drawViewWithCacheKey:(NSString *)cacheKey drawBlock = [drawBlock copy]; completionBlock = [completionBlock copy]; + NSArray *completionBlocksForCacheKey = [self.inProgessKeyToCompletionBlocksDictionary objectForKey:cacheKey]; + if (completionBlocksForCacheKey) + { + completionBlocksForCacheKey = [completionBlocksForCacheKey arrayByAddingObject:completionBlock]; + [self.inProgessKeyToCompletionBlocksDictionary setObject:completionBlocksForCacheKey forKey:cacheKey]; + return; + } + else + { + completionBlocksForCacheKey = @[completionBlock]; + [self.inProgessKeyToCompletionBlocksDictionary setObject:completionBlocksForCacheKey forKey:cacheKey]; + } + dispatch_block_t loadImageBlock = ^{ BOOL opaque = [self colorIsOpaque:backgroundColor]; @@ -109,17 +126,17 @@ - (void)drawViewWithCacheKey:(NSString *)cacheKey resultImage = UIGraphicsGetImageFromCurrentImageContext(); } UIGraphicsEndImageContext(); - + if (resultImage) [self.cache setObject:resultImage forKey:cacheKey]; - + if (waitUntilDone) { - completionBlock(resultImage); + [self callCompletionBlocksForCacheKey:cacheKey image:resultImage]; } else { dispatch_async(dispatch_get_main_queue(), ^{ - completionBlock(resultImage); + [self callCompletionBlocksForCacheKey:cacheKey image:resultImage]; }); } }; @@ -134,6 +151,15 @@ - (void)drawViewWithCacheKey:(NSString *)cacheKey } } +- (void)callCompletionBlocksForCacheKey:(NSString *)cacheKey image:(UIImage *)image +{ + for (MSCachedAsyncViewDrawingCompletionBlock completionBlock in [self.inProgessKeyToCompletionBlocksDictionary objectForKey:cacheKey]) + { + completionBlock(image); + } + [self.inProgessKeyToCompletionBlocksDictionary removeObjectForKey:cacheKey]; +} + #pragma mark - Public - (void)drawViewAsyncWithCacheKey:(NSString *)cacheKey From 53587578a00e4e7900b8c98b442e1e8f48fae44a Mon Sep 17 00:00:00 2001 From: Jacob Jennings Date: Sat, 8 Dec 2012 11:23:19 -0800 Subject: [PATCH 3/3] Revert "Keep track of in-progress tasks to avoid duplication of effort. Also, avoid inserting nil image into cache." This reverts commit f9be0bfb0d689d27f81d83c409fc635910bbd4ec. --- MSCachedAsyncViewDrawing.m | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/MSCachedAsyncViewDrawing.m b/MSCachedAsyncViewDrawing.m index 34985e8..db29db9 100644 --- a/MSCachedAsyncViewDrawing.m +++ b/MSCachedAsyncViewDrawing.m @@ -23,7 +23,6 @@ @interface MSCachedAsyncViewDrawing () @property (nonatomic, strong) NSCache *cache; -@property (nonatomic, strong) NSMutableDictionary *inProgessKeyToCompletionBlocksDictionary; @property (nonatomic, MS_dispatch_queue_t_property_qualifier) dispatch_queue_t dispatchQueue; @@ -49,9 +48,6 @@ - (id)init { self.cache = [[NSCache alloc] init]; self.cache.name = @"com.mindsnacks.view_drawing.cache"; - - self.inProgessKeyToCompletionBlocksDictionary = [[NSMutableDictionary alloc] init]; - self.dispatchQueue = dispatch_queue_create("com.mindsnacks.view_drawing.queue", DISPATCH_QUEUE_CONCURRENT); } @@ -85,19 +81,6 @@ - (void)drawViewWithCacheKey:(NSString *)cacheKey drawBlock = [drawBlock copy]; completionBlock = [completionBlock copy]; - NSArray *completionBlocksForCacheKey = [self.inProgessKeyToCompletionBlocksDictionary objectForKey:cacheKey]; - if (completionBlocksForCacheKey) - { - completionBlocksForCacheKey = [completionBlocksForCacheKey arrayByAddingObject:completionBlock]; - [self.inProgessKeyToCompletionBlocksDictionary setObject:completionBlocksForCacheKey forKey:cacheKey]; - return; - } - else - { - completionBlocksForCacheKey = @[completionBlock]; - [self.inProgessKeyToCompletionBlocksDictionary setObject:completionBlocksForCacheKey forKey:cacheKey]; - } - dispatch_block_t loadImageBlock = ^{ BOOL opaque = [self colorIsOpaque:backgroundColor]; @@ -126,17 +109,17 @@ - (void)drawViewWithCacheKey:(NSString *)cacheKey resultImage = UIGraphicsGetImageFromCurrentImageContext(); } UIGraphicsEndImageContext(); - + if (resultImage) [self.cache setObject:resultImage forKey:cacheKey]; - + if (waitUntilDone) { - [self callCompletionBlocksForCacheKey:cacheKey image:resultImage]; + completionBlock(resultImage); } else { dispatch_async(dispatch_get_main_queue(), ^{ - [self callCompletionBlocksForCacheKey:cacheKey image:resultImage]; + completionBlock(resultImage); }); } }; @@ -151,15 +134,6 @@ - (void)drawViewWithCacheKey:(NSString *)cacheKey } } -- (void)callCompletionBlocksForCacheKey:(NSString *)cacheKey image:(UIImage *)image -{ - for (MSCachedAsyncViewDrawingCompletionBlock completionBlock in [self.inProgessKeyToCompletionBlocksDictionary objectForKey:cacheKey]) - { - completionBlock(image); - } - [self.inProgessKeyToCompletionBlocksDictionary removeObjectForKey:cacheKey]; -} - #pragma mark - Public - (void)drawViewAsyncWithCacheKey:(NSString *)cacheKey