Created
November 23, 2012 12:23
-
-
Save sodastsai/4135395 to your computer and use it in GitHub Desktop.
Internal Storage with KVO
This file contains hidden or 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 ISStorage : NSObject | |
| + (ISStorage *)sharedStorage; | |
| - (id)valueForKeyInInternalStorage:(NSString *)key; | |
| - (void)setValue:(id)value forKeyInInternalStorage:(NSString *)key; | |
| @end |
This file contains hidden or 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 "ISStorage.h" | |
| @interface ISStorage () { | |
| NSMutableDictionary *_internalStorage; | |
| NSString *_filePath; | |
| } | |
| @property (nonatomic, getter=isDirty) BOOL dirty; | |
| @end | |
| @implementation ISStorage | |
| + (ISStorage *)sharedStorage { | |
| static dispatch_once_t onceToken; | |
| static ISStorage *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.plist"]; | |
| // Create pool | |
| _internalStorage = [NSMutableDictionary dictionaryWithContentsOfFile:_filePath]; | |
| if (!_internalStorage) { | |
| // No file. Create new one | |
| _internalStorage = [NSMutableDictionary dictionary]; | |
| } | |
| _dirty = NO; | |
| // ************************************************************** // | |
| // KVO | |
| [self addObserver:self forKeyPath:@"dirty" options:NSKeyValueObservingOptionNew context:NULL]; | |
| // ************************************************************** // | |
| } | |
| return self; | |
| } | |
| - (void)dealloc { | |
| [self removeObserver:self forKeyPath:@"dirty"]; | |
| } | |
| #pragma mark - KVO | |
| - (void)observeValueForKeyPath:(NSString *)keyPath | |
| ofObject:(id)object | |
| change:(NSDictionary *)change | |
| context:(void *)context { | |
| if ([keyPath isEqualToString:@"dirty"]) { | |
| BOOL newDirtyValue = [change[NSKeyValueChangeNewKey] boolValue]; | |
| if (newDirtyValue) { | |
| // Update after 5 sec | |
| int64_t delayInSeconds = 5.0f; | |
| dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); | |
| // In background thread | |
| dispatch_queue_t globalBackgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); | |
| // Go! | |
| dispatch_after(popTime, globalBackgroundQueue, ^(void){ | |
| [_internalStorage writeToFile:_filePath atomically:YES]; | |
| _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 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When using this implementation
===> It only does Disk I/O 4 times.
===> The code for writing disk is never called.
===> The change is not saved and lost.