@@ -150,6 +150,80 @@ - (NSString *)decodedString:(NSString *)string
150150 return (__bridge_transfer NSString *)unescapedString;
151151}
152152
153+ #pragma mark - Private Trash Methods -
154+
155+ + (dispatch_queue_t )sharedTrashQueue
156+ {
157+ static dispatch_queue_t trashQueue;
158+ static dispatch_once_t predicate;
159+
160+ dispatch_once (&predicate, ^{
161+ NSString *queueName = [[NSString alloc ] initWithFormat: @" %@ .trash" , TMDiskCachePrefix];
162+ trashQueue = dispatch_queue_create ([queueName UTF8String ], DISPATCH_QUEUE_SERIAL);
163+ dispatch_set_target_queue (trashQueue, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0 ));
164+ });
165+
166+ return trashQueue;
167+ }
168+
169+ + (NSURL *)sharedTrashURL
170+ {
171+ static NSURL *sharedTrashURL;
172+ static dispatch_once_t predicate;
173+
174+ dispatch_once (&predicate, ^{
175+ sharedTrashURL = [[[NSURL alloc ] initFileURLWithPath: NSTemporaryDirectory ()] URLByAppendingPathComponent: TMDiskCachePrefix isDirectory: YES ];
176+
177+ dispatch_async ([self sharedTrashQueue ], ^{
178+ if (![[NSFileManager defaultManager ] fileExistsAtPath: [sharedTrashURL path ]]) {
179+ NSError *error = nil ;
180+ [[NSFileManager defaultManager ] createDirectoryAtURL: sharedTrashURL
181+ withIntermediateDirectories: YES
182+ attributes: nil
183+ error: &error];
184+ TMDiskCacheError (error);
185+ }
186+ });
187+ });
188+
189+ return sharedTrashURL;
190+ }
191+
192+ +(BOOL )moveItemAtURLToTrash : (NSURL *)itemURL
193+ {
194+ if (![[NSFileManager defaultManager ] fileExistsAtPath: [itemURL path ]])
195+ return NO ;
196+
197+ NSError *error = nil ;
198+ NSString *uniqueString = [[NSProcessInfo processInfo ] globallyUniqueString ];
199+ NSURL *uniqueTrashURL = [[TMDiskCache sharedTrashURL ] URLByAppendingPathComponent: uniqueString];
200+ BOOL moved = [[NSFileManager defaultManager ] moveItemAtURL: itemURL toURL: uniqueTrashURL error: &error];
201+ TMDiskCacheError (error);
202+ return moved;
203+ }
204+
205+ + (void )emptyTrash
206+ {
207+ TMCacheStartBackgroundTask ();
208+
209+ dispatch_async ([self sharedTrashQueue ], ^{
210+ NSError *error = nil ;
211+ NSArray *trashedItems = [[NSFileManager defaultManager ] contentsOfDirectoryAtURL: [self sharedTrashURL ]
212+ includingPropertiesForKeys: nil
213+ options: 0
214+ error: &error];
215+ TMDiskCacheError (error);
216+
217+ for (NSURL *trashedItemURL in trashedItems) {
218+ NSError *error = nil ;
219+ [[NSFileManager defaultManager ] removeItemAtURL: trashedItemURL error: &error];
220+ TMDiskCacheError (error);
221+ }
222+
223+ TMCacheEndBackgroundTask ();
224+ });
225+ }
226+
153227#pragma mark - Private Queue Methods -
154228
155229- (BOOL )createCacheDirectory
@@ -224,12 +298,11 @@ - (BOOL)removeFileAndExecuteBlocksForKey:(NSString *)key
224298 if (_willRemoveObjectBlock)
225299 _willRemoveObjectBlock (self, key, nil , fileURL);
226300
227- NSError *error = nil ;
228- BOOL removed = [[NSFileManager defaultManager ] removeItemAtURL: fileURL error: &error];
229- TMDiskCacheError (error);
230-
231- if (!removed)
301+ BOOL trashed = [TMDiskCache moveItemAtURLToTrash: fileURL];
302+ if (!trashed)
232303 return NO ;
304+
305+ [TMDiskCache emptyTrash ];
233306
234307 NSNumber *byteSize = [_sizes objectForKey: key];
235308 if (byteSize)
@@ -409,7 +482,7 @@ - (void)setObject:(id)object forKey:(NSString *)key writeBlock:(TMDiskCacheWrite
409482 if (written) {
410483 [strongSelf setFileModificationDate: now forURL: fileURL];
411484
412- error = nil ;
485+ NSError * error = nil ;
413486 NSDictionary *values = [fileURL resourceValuesForKeys: @[ NSURLTotalFileAllocatedSizeKey ] error: &error];
414487 TMDiskCacheError (error);
415488
@@ -560,12 +633,9 @@ - (void)removeAllObjects:(TMDiskCacheBlock)block
560633
561634 if (strongSelf->_willRemoveAllObjectsBlock )
562635 strongSelf->_willRemoveAllObjectsBlock (strongSelf);
563-
564- if ([[NSFileManager defaultManager ] fileExistsAtPath: [strongSelf->_cacheURL path ]]) {
565- NSError *error = nil ;
566- [[NSFileManager defaultManager ] removeItemAtURL: strongSelf->_cacheURL error: &error];
567- TMDiskCacheError (error);
568- }
636+
637+ [TMDiskCache moveItemAtURLToTrash: strongSelf->_cacheURL];
638+ [TMDiskCache emptyTrash ];
569639
570640 [strongSelf createCacheDirectory ];
571641
@@ -624,23 +694,22 @@ - (id)objectForKey:(NSString *)key readBlock:(TMDiskCacheReadBlock)readBlock
624694{
625695 if (!key)
626696 return nil ;
627-
628- __block id <NSCoding > objectForKey = nil ;
629-
630- dispatch_semaphore_t semaphore = dispatch_semaphore_create (0 );
631-
632- [self objectForKey: key readBlock: readBlock block: ^(TMDiskCache *cache, NSString *key, id <NSCoding > object, NSURL *fileURL) {
633- objectForKey = object;
634- dispatch_semaphore_signal (semaphore);
635- }];
636697
637- dispatch_semaphore_wait (semaphore, DISPATCH_TIME_FOREVER);
638-
639- #if !OS_OBJECT_USE_OBJC
640- dispatch_release (semaphore);
641- #endif
642-
643- return objectForKey;
698+ NSURL *fileURL = [self encodedFileURLForKey: key];
699+
700+ // No need to check if file exists, as unarchiveObjectWithFile returns nil if there is no file at path
701+ id <NSCoding > object = [NSKeyedUnarchiver unarchiveObjectWithFile: [fileURL path ]];
702+
703+ if (object) {
704+ __weak TMDiskCache *weakSelf = self;
705+ dispatch_barrier_async (_queue, ^{
706+ TMDiskCache *strongSelf = weakSelf;
707+ if (strongSelf)
708+ [strongSelf setFileModificationDate: [NSDate new ] forURL: fileURL];
709+ });
710+ }
711+
712+ return object;
644713}
645714
646715- (NSURL *)fileURLForKey : (NSString *)key
0 commit comments