备忘录模式很简单,就是存储对象,然后支持恢复对象到之前的某个状态,玩过游戏的,一定懂得存档一说,备忘录就是对对象的存档与管理。
效果:
这个需要配合FastCoder使用,请自行到Github上去搜索源码FastCoder源码^_^!
源码:
Model.h 与 Model.m
// // Model.h // MementoPattern // // Created by YouXianMing on 15/1/3. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import <Foundation/Foundation.h> @interface Model : NSObject @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *age; /** * 初始化方法 * * @param key 用来标示对象唯一性 * * @return 对象 */ - (instancetype)initWithKey:(NSString *)key; /** * 从某个状态恢复 * * @param slot 状态槽位(第几个存档位置) * @param key 标示字符串(保证存档唯一) * * @return 存档的对象,如果对象不存在,则重新创建 */ + (id)recoverFromSlot:(NSInteger)slot key:(NSString *)key; /** * 存储到slot当中(按照数组的顺序) */ - (void)store; @end
// // Model.m // MementoPattern // // Created by YouXianMing on 15/1/3. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "Model.h" #import "FastCoder.h" #import "NSString+File.h" @interface Model () @property (nonatomic, strong) NSString *key; @property (nonatomic, strong) NSMutableArray *slotInfoArray; @end @implementation Model - (instancetype)init { self = [super init]; if (self) { self.key = @"Default"; } return self; } - (instancetype)initWithKey:(NSString *)key { Model *model = [Model new]; model.key = key; return model; } + (id)recoverFromSlot:(NSInteger)slot key:(NSString *)key { if (key == nil) { key = @"Default"; } NSString *arrayPath = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_array", key]]; NSString *objectPath = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_%ld", key, (long)slot]]; id object = nil; NSArray *array = [FastCoder objectWithData:[self dataWithPath:arrayPath]]; if (array.count > slot && slot >= 0) { object = [FastCoder objectWithData:[self dataWithPath:objectPath]]; } return object; } - (void)store { if (self == nil) { return; } self.slotInfoArray = [FastCoder objectWithData:[self dataWithPath:[self arrayPath]]]; if (self.slotInfoArray.count == 0) { [[FastCoder dataWithRootObject:self] writeToFile:[self filePathAtSlot:0] atomically:YES]; self.slotInfoArray = [NSMutableArray array]; [self.slotInfoArray addObject:@""]; [[FastCoder dataWithRootObject:self.slotInfoArray] writeToFile:[self arrayPath] atomically:YES]; } else { [[FastCoder dataWithRootObject:self] writeToFile:[self filePathAtSlot:self.slotInfoArray.count] atomically:YES]; [self.slotInfoArray addObject:@""]; [[FastCoder dataWithRootObject:self.slotInfoArray] writeToFile:[self arrayPath] atomically:YES]; } NSLog(@"store sucess!"); } #pragma mark - private method - (NSString *)filePathAtSlot:(NSInteger)slot { NSString *path = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_%ld", self.key, (long)slot]]; return path; } - (NSString *)arrayPath { NSString *path = [[@"/Documents" path] stringByAppendingString:[NSString stringWithFormat:@"/%@_array", self.key]]; return path; } - (NSData *)dataWithPath:(NSString *)path { return [NSData dataWithContentsOfFile:path]; } + (NSData *)dataWithPath:(NSString *)path { return [NSData dataWithContentsOfFile:path]; } @end
NSString+File.h 与 NSString+File.m
// // NSString+File.h // Category // // Created by YouXianMing on 14-8-29. // Copyright (c) 2014年 YouXianMing. All rights reserved. // #import <Foundation/Foundation.h> @interface NSString (File) // 沙盒路径 - (NSString *)path; /* /Documents /Library/Caches /Library/Preferences /tmp */ // bundle文件 - (NSString *)bundleFile; // 检测文件或者文件夹是否存在 - (BOOL)exist; // 创建文件夹 - (BOOL)createFolder; // 是否是文件夹 - (BOOL)isDirectory; // 复制到这个路径 - (BOOL)copyTo:(NSString *)path; // 移动到这个路径 - (BOOL)moveTo:(NSString *)path; // 删除文件 - (BOOL)remove; // 遍历出文件夹中的文件 - (NSArray *)enumeratorFolder; // 遍历出文件夹并在block中查看 - (void)enumeratorFolderEach:(void (^)(NSString *path))block; // 文件信息 - (NSDictionary *)fileInfo; // 文件大小 - (int)fileSize; @end
// // NSString+File.m // Category // // Created by YouXianMing on 14-8-29. // Copyright (c) 2014年 YouXianMing. All rights reserved. // #import "NSString+File.h" @implementation NSString (File) - (NSString *)path { return [NSHomeDirectory() stringByAppendingPathComponent:self]; } - (NSString *)bundleFile { return [[NSBundle mainBundle] pathForResource:self ofType:nil]; } - (BOOL)exist { return [[NSFileManager defaultManager] fileExistsAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] isDirectory:NO]; } - (BOOL)createFolder { return [[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] withIntermediateDirectories:YES attributes:nil error:nil]; } - (BOOL)isDirectory { BOOL isDirectory = NO; [[NSFileManager defaultManager] fileExistsAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] isDirectory:&isDirectory]; return isDirectory; } - (BOOL)copyTo:(NSString *)path { return [[NSFileManager defaultManager] copyItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] toPath:[NSHomeDirectory() stringByAppendingPathComponent:path] error:nil]; } - (BOOL)moveTo:(NSString *)path { return [[NSFileManager defaultManager] moveItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] toPath:[NSHomeDirectory() stringByAppendingPathComponent:path] error:nil]; } - (BOOL)remove { return [[NSFileManager defaultManager] removeItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] error:nil]; } - (NSArray *)enumeratorFolder { if ([self isDirectory]) { NSMutableArray *storeArray = [NSMutableArray array]; NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent:self]; NSFileManager *localFileManager = [[NSFileManager alloc] init]; NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:docsDir]; NSString *file; while ((file = [dirEnum nextObject])) { [storeArray addObject:[[NSHomeDirectory() stringByAppendingPathComponent:self] stringByAppendingPathComponent:file]]; } return storeArray; } else { return nil; } } - (void)enumeratorFolderEach:(void (^)(NSString *path))block { if ([self isDirectory]) { NSMutableArray *storeArray = [NSMutableArray array]; NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent:self]; NSFileManager *localFileManager = [[NSFileManager alloc] init]; NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:docsDir]; NSString *file; while ((file = [dirEnum nextObject])) { [storeArray addObject:[self stringByAppendingPathComponent:file]]; } [storeArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { block(obj); }]; } } - (NSDictionary *)fileInfo { return [[NSFileManager defaultManager] attributesOfItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] error:nil]; } - (int)fileSize { return [[[[NSFileManager defaultManager] attributesOfItemAtPath:[NSHomeDirectory() stringByAppendingPathComponent:self] error:nil] objectForKey:@"NSFileSize"] intValue]; } @end
控制器源码:
// // ViewController.m // MementoPattern // // Created by YouXianMing on 15/1/3. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "NSString+File.h" #import "Model.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; Model *model_01 = [Model new]; model_01.name = @"YouXianMing"; model_01.age = @"27"; [model_01 store]; // 存快照 Model *model_02 = [Model new]; model_02.name = @"QiuLiang"; model_02.age = @"28"; [model_02 store]; // 存快照 Model *model_03 = [Model new]; model_03.name = @"XiaoMing"; model_03.age = @"100"; [model_03 store]; // 存快照 // Model *test_model_01 = [Model recoverFromSlot:0 key:nil]; // NSLog(@"%@ %@", test_model_01.name, test_model_01.age); // // Model *test_model_02 = [Model recoverFromSlot:1 key:nil]; // NSLog(@"%@ %@", test_model_02.name, test_model_02.age); // // Model *test_model_03 = [Model recoverFromSlot:2 key:nil]; // NSLog(@"%@ %@", test_model_03.name, test_model_03.age); } @end
几个关键的地方:
原理其实非常简单,就是将对象写文件,然后从文件从恢复出对象,但一定要有管理的功能,本例中并没有处理如何删除存档,其实存档可以做成堆栈或者队列模式,这个因需求而已,本处本人只是抛砖引玉,简单介绍下备忘录设计模式!
时间: 2024-12-13 19:46:02