Created
November 23, 2012 12:27
-
-
Save sodastsai/4135411 to your computer and use it in GitHub Desktop.
Internal Storage with NSTimer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface ISTimerStorage : NSObject | |
+ (ISTimerStorage *)sharedStorage; | |
- (id)valueForKeyInInternalStorage:(NSString *)key; | |
- (void)setValue:(id)value forKeyInInternalStorage:(NSString *)key; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ISTimerStorage.h" | |
@interface ISTimerStorage () { | |
NSMutableDictionary *_internalStorage; | |
NSString *_filePath; | |
} | |
@property (nonatomic, getter=isDirty) BOOL dirty; | |
@end | |
@implementation ISTimerStorage | |
+ (ISTimerStorage *)sharedStorage { | |
static dispatch_once_t onceToken; | |
static ISTimerStorage *sharedStorage = nil; | |
dispatch_once(&onceToken, ^{ | |
sharedStorage = [[self alloc] init]; | |
}); | |
return sharedStorage; | |
} | |
- (id)init { | |
if (self = [super init]) { | |
// File Path | |
NSString *docDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; | |
_filePath = [docDirectory stringByAppendingPathComponent:@"internal_timer.plist"]; | |
// Create pool | |
_internalStorage = [NSMutableDictionary dictionaryWithContentsOfFile:_filePath]; | |
if (!_internalStorage) { | |
// No file. Create new one | |
_internalStorage = [NSMutableDictionary dictionary]; | |
} | |
_dirty = NO; | |
// ************************************************************** // | |
// Timer | |
[NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:@selector(save) userInfo:nil repeats:YES]; | |
// ************************************************************** // | |
} | |
return self; | |
} | |
#pragma mark - Timer | |
- (void)save { | |
if (self.dirty) { | |
// Save in background | |
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); | |
dispatch_async(backgroundQueue, ^{ | |
[_internalStorage writeToFile:_filePath atomically:YES]; | |
self.dirty = NO; | |
}); | |
} | |
} | |
#pragma mark - Interface | |
- (id)valueForKeyInInternalStorage:(NSString *)key { | |
return _internalStorage[key]; | |
} | |
- (void)setValue:(id)value forKeyInInternalStorage:(NSString *)key { | |
if (!value) return; | |
_internalStorage[key] = value; | |
self.dirty = YES; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When using this implementation
If I change the content of internal storage frequently (about 100 times) in 20 seconds
===> It only does Disk I/O 4 times.
If I leave my app running in 1 minutes without changing the content of internal storage
===> The code for writing disk is called every 5 seconds. So it runs 20 times additional.
If my app crashes after changing the content of internal storage in "5" seconds
===> The change is not saved and lost.