Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #import "MVStateStorage.h"
- @implementation MVStateStorage
- - (id)init {
- self = [super init];
- if (self) {
- data = [[NSMutableDictionary alloc] init];
- queues = [[NSMutableDictionary alloc] init];
- }
- return self;
- }
- - (void)dealloc {
- [queues enumerateKeysAndObjectsUsingBlock:^(id key, NSOperationQueue *obj, BOOL *s) {
- [obj cancelAllOperations];
- [obj waitUntilAllOperationsAreFinished];
- [obj setSuspended:YES];
- }];
- [queues release];
- [data release];
- [super dealloc];
- }
- - (NSOperationQueue *)queueForKey:(id)key {
- NSOperationQueue *q = [queues objectForKey:key];
- if (!q) {
- @synchronized(queues) {
- q = [[NSOperationQueue alloc] init];
- [q setMaxConcurrentOperationCount:1];
- [queues setObject:q forKey:key];
- [q release];
- }
- }
- return q;
- }
- - (void)cancelOperationsForKey:(id)key {
- [[self queueForKey:key] cancelAllOperations];
- }
- - (void)scheduleBlock:(MVStateOpBlock)block forKey:(id)key {
- NSOperationQueue *q = [self queueForKey:key];
- [q addOperationWithBlock:^{
- id val = nil;
- id res = nil;
- @synchronized(data) {
- val = [data objectForKey:key];
- }
- NSAutoreleasePool *p = [NSAutoreleasePool new];
- res = block(val);
- if (val != res) {
- if (!res) {
- [[NSOperationQueue currentQueue] cancelAllOperations];
- @synchronized(data) {
- [data removeObjectForKey:key];
- }
- return;
- }
- else {
- @synchronized(data) {
- [data setObject:res forKey:key];
- }
- }
- }
- [p release];
- }];
- }
- #define PREVENT \
- if (preventAccess) {\
- [NSException raise:NSInternalInconsistencyException format:@"Setter function called in operation *setup* block."];\
- }
- - (void)setupOperationForKey:(id)key withBlock:(MVOpSetupBlock)block {
- NSOperationQueue *q = [self queueForKey:key];
- __block BOOL preventAccess = YES;
- __block id cachedVal = nil;
- MVGetterBlock getter = ^{
- PREVENT
- if (cachedVal) return cachedVal;
- @synchronized(data) {
- return [data objectForKey:key];
- }
- };
- MVSetterBlock setter = ^(id newVal) {
- PREVENT
- @synchronized(data) {
- cachedVal = newVal;
- [data setObject:newVal forKey:key];
- }
- };
- NSAutoreleasePool *p = [NSAutoreleasePool new];
- NSOperation *op = block(getter, setter);
- preventAccess = NO;
- cachedVal = nil;
- [q addOperation:op];
- [p release];
- }
- #undef PREVENT
- - (NSDictionary *)dictionaryRepresentation {
- @synchronized(data) {
- return [[[NSDictionary alloc] initWithDictionary:data copyItems:YES] autorelease];
- }
- }
- - (NSArray *)allKeys {
- @synchronized(data) {
- return [[[data allKeys] copy] autorelease];
- }
- }
- @end
Add Comment
Please, Sign In to add comment