Want to take your software engineering career to the next level? Join the mailing list for career tips & advice Click here

TMCache

Fast parallel object cache for iOS and OS X.

Subscribe to updates I use TMCache


Statistics on TMCache

Number of watchers on Github 3071
Number of open issues 17
Average time to close an issue 2 months
Main language Objective-C
Average time to merge a PR 2 months
Open pull requests 6+
Closed pull requests 8+
Last commit over 5 years ago
Repo Created almost 8 years ago
Repo Last Updated over 2 years ago
Size 3.7 MB
Organization / Authortumblr
Latest Release2.1.0
Contributors11
Page Updated
Do you use TMCache? Leave a review!
View open issues (17)
View TMCache activity
View on github
Book a Mock Interview With Me (Silicon Valley Engineering Leader, 100s of interviews conducted)
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Evaluating TMCache for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

TMCache

:warning: :warning: :warning: TMCACHE IS NO LONGER BEING ACTIVELY MAINTAINED. DETAILS HERE.

Fast parallel object cache for iOS and OS X.

Build Status Version Platform License

TMCache is a key/value store designed for persisting temporary objects that are expensive to reproduce, such as downloaded data or the results of slow processing. It is comprised of two self-similar stores, one in memory (TMMemoryCache) and one on disk (TMDiskCache), all backed by GCD and safe to access from multiple threads simultaneously. On iOS, TMMemoryCache will clear itself when the app receives a memory warning or goes into the background. Objects stored in TMDiskCache remain until you trim the cache yourself, either manually or by setting a byte or age limit.

TMCache and TMDiskCache accept any object conforming to NSCoding. Put things in like this:

UIImage *img = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] scale]];
[[TMCache sharedCache] setObject:img forKey:@"image" block:nil]; // returns immediately

Get them back out like this:

[[TMCache sharedCache] objectForKey:@"image"
                              block:^(TMCache *cache, NSString *key, id object) {
                                  UIImage *image = (UIImage *)object;
                                  NSLog(@"image scale: %f", image.scale);
                              }];

TMMemoryCache allows for concurrent reads and serialized writes, while TMDiskCache serializes disk access across all instances in the app to increase performance and prevent file contention. TMCache coordinates them so that objects added to memory are available immediately to other threads while being written to disk safely in the background. Both caches are public properties of TMCache, so it's easy to manipulate one or the other separately if necessary.

Collections work too. Thanks to the magic of NSKeyedArchiver, objects repeated in a collection only occupy the space of one on disk:

NSArray *images = @[ image, image, image ];
[[TMCache sharedCache] setObject:images forKey:@"images"];
NSLog(@"3 for the price of 1: %d", [[[TMCache sharedCache] diskCache] byteCount]);

Installation

Manually

Download the latest tag and drag the TMCache folder into your Xcode project.

Install the docs by double clicking the .docset file under docs/, or view them online at cocoadocs.org

Git Submodule

git submodule add https://github.com/tumblr/TMCache.git
git submodule update --init

CocoaPods

Add TMCache to your Podfile and run pod install.

Requirements

TMCache requires iOS 5.0 or OS X 10.7 and greater.

Contributing

Please see CONTRIBUTING.md for information on how to help out.

Contact

Bryan Irace

License

Copyright 2013 Tumblr, Inc.

Licensed under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

TMCache open issues Ask a question     (View All Issues)
  • over 5 years setObject not working
  • over 5 years Memory warning block did not execute
  • over 5 years ageLimit is not an ageLimit
  • almost 6 years Completion block is not called
  • about 6 years cache life time
  • about 6 years encodedString
  • about 6 years Remove shadowing of variables
  • almost 7 years Potential cache race can result in memory/disk cache inconsistency
  • almost 7 years isPresentObjectForKey
  • over 7 years TMDiskCache fails silently when keys are too long
TMCache open pull requests (View All Pulls)
  • fix block may not be called
  • Modernization
  • option to prevent cache reads from updating entry's modification date
  • Resolves deadlock issues by making synchronous objectForKey: methods truly synchronous
  • Add readBlock to objectForKey: and writeBlock to setObject:forKey:
  • Add fileURLForKey:updateFileModificationDate:block:
TMCache questions on Stackoverflow (View All Questions)
  • CocoaPods TMCache Error
  • TMCache - using Blocks to Monitor Cache Events
TMCache list of languages used
TMCache latest release notes

Removes the need for the explicit memory warning and application background handling, which was an ill-advised change in 2.0.

The other part of the 2.0 release still applies; you need to explicitly provide an object that knows how to vend background tasks in order for operations to continue after your application has been backgrounded.

2.0.0 removes all references to UIApplication sharedApplication. As of iOS 8, this method is annotated with NS_EXTENSION_UNAVAILABLE_IOS, meaning that it wont compile as part of an iOS 8 extension. In order to facilitate TMCache usage inside extensions.

TMCache previously used UIApplication for two different functions:

  • Wrapping work in background tasks, to ensure that it completes even if the user backgrounds the application
  • Listening for UIApplicationDidEnterBackgroundNotification and UIApplicationDidReceiveMemoryWarningNotification, in order to perform some cleanup work

If you still want this behavior, its now up to you to implement this behavior in your application code. Thankfully, doing so is extremely straightforward:

Background tasks

Create a class that conforms to TMCacheBackgroundTaskManager. Your implementation will likely look very much like this:

Objective-C:

@interface BackgroundTaskManager: NSObject <TMCacheBackgroundTaskManager>

@implementation BackgroundTaskManger

- (UIBackgroundTaskIdentifier)beginBackgroundTask {
    UIBackgroundTaskIdentifier taskID = UIBackgroundTaskInvalid;

    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [[UIApplication sharedApplication] endBackgroundTask:taskID];
    }];

    return taskID;
}

- (void)endBackgroundTask:(UIBackgroundTaskIdentifier)identifier {
    [[UIApplication sharedApplication] endBackgroundTask:identifier];
}

@end

Swift:

class BackgroundTaskManager: NSObject, TMCacheBackgroundTaskManager {
    private let application = UIApplication.sharedApplication()

    func beginBackgroundTask() -> UInt {
        let taskID = UIBackgroundTaskInvalid

        application.beginBackgroundTaskWithExpirationHandler {
            self.application.endBackgroundTask(taskID)
        }

        return UInt(taskID)
    }

    func endBackgroundTask(identifier: UInt) {
        application.endBackgroundTask(Int(identifier))
    }
}

Then, pass an instance of your class to the following TMDiskCache class method:

[TMDiskCache setBackgroundTaskManager:[[BackgroundTaskManager alloc] init]];

Clean-up on memory warning/backgrounding notifications

TMMemoryCache has new public methods that can be called in the event of a memory warning or application backgrounding, in order to easily replicate TMCache 1.X.X behavior:

Objective-C:

[[NSNotificationCenter defaultCenter] addObserver:memoryCache
                                         selector:@selector(handleMemoryWarning)        
                                             name:UIApplicationDidReceiveMemoryWarningNotification     
                                           object:[UIApplication sharedApplication]];

[[NSNotificationCenter defaultCenter] addObserver:memoryCache
                                         selector:@selector(handleApplicationBackgrounding)        
                                             name:UIApplicationDidEnterBackgroundNotification     
                                           object:[UIApplication sharedApplication]];

Swift:

NSNotificationCenter.defaultCenter().addObserver(memoryCache, selector: "handleMemoryWarning", name: UIApplicationDidReceiveMemoryWarningNotification, object: UIApplication.sharedApplication())

NSNotificationCenter.defaultCenter().addObserver(memoryCache, selector: "handleApplicationBackgrounding", name: UIApplicationDidEnterBackgroundNotification, object: UIApplication.sharedApplication())
  • [fix] TMDiskCache/TMMemoryCache: import UIKit to facilitate Swift usage (thanks digabriel!)
  • [fix] TMDiskCache: add try catch to ensure an exception isnt thrown if a file on disk is unable to be unarchived (thanks leonskywalker!)
  • [fix] TMDiskCache: create trash directory asynchronously to avoid race condition (thanks napoapo77!)
Other projects in Objective-C
Powered by Autocode - Instant Webhooks, Scripts and APIs
Autocode logo wordmark