这个库是在Casa老师在[《OS应用架构谈 本地持久化方案及动态部署》]这篇文章(http://casatwy.com/iosying-yong-jia-gou-tan-ben-di-chi-jiu-hua-fang-an-ji-dong-tai-bu-shu.html)里给出一个持久化方案的实现,比起Key Value的简单存储,这个库基于SQLite,提供了对弱业务(数据操作)封装,非常适用于有状态的数据持久化。我上个月调查了几种key value的持久化方式,也再次看了这个方案。对我们只需要key-value存储的应用来说,这个持久化方案显得重型了一点。我也是草草看了两遍源码,没有具体整理。最有效的学习方式还是使用并修改源码。
对这个方案里的,强业务弱业务的分离,数据表达和数据操作的分离有点明白,但是没在项目里用上,也就没有什么特别的心得。以后应该还会回到这里,接下来会把精力方案单元测试和网络的项目内容。
我觉得作者Tian Wei Yu (AKA: Casa Taloyum),是我的榜样。技术好,文章写得也好,还非常热心,基本上是有问必答,他的博客上有常常的回复列表。在这浮躁的技术界实在是少见。我通读了他iOS应用架构谈的几篇文章,受益匪浅,值得好好研究。
问题
1)CTPersistanceTable的 isFromMigration属性怎么使用,数据库迁移的时候要注意些什么?
2)CTPersistanceQueryCommand.m line 72 如果传进来的error为nil,函数调用失败返回YES,而不是NO
总结
1)版本迁移的步骤
在创建数据库对象时,判断是否需要迁移,并执行迁移。具体是在 CTPersistanceDataBase 类的 - (instancetype)initWithDatabaseName:(NSString *)databaseName error:(NSError *__autoreleasing *)error 方法。
数据库中有一张叫做 CTPersistanceVersionTable的表,记录当前的数据库版本。表只有2个字段,一条记录。如果表中无记录,用 CTPersistanceMigrator的 migrationVersionList第一条记录初始化它。
+ (NSDictionary *)columnInfo{ return @{ @"identifier":@"INTEGER PRIMARY KEY AUTOINCREMENT", @"databaseVersion":@"TEXT" }; }
一个数据库对应一个Migrator,Migrator的migrationVersionList,记录数据库的迁移的所有版本。每个版本对应一个遵守 CTPersistanceMigrationStep协议的MigrationStep类,这个类里提供了对应版本的向上和向下迁移的方法。
@implementation TestMigrator#pragma mark - CTPersistanceMigratorProtocol- (NSDictionary *)migrationStepDictionary{ return @{ @"1.0":[MigrationStep1_0 class], @"2.0":[MigrationStep2_0 class] };}
- (NSArray *)migrationVersionList{ return @[kCTPersistanceInitVersion, @"1.0", @"2.0"]; } @end
@implementation MigrationStep1_0- (void)goUpWithQueryCommand:(CTPersistanceQueryCommand *)queryCommand error:(NSError *__autoreleasing *)error{ TestTable *testTable = [[TestTable alloc] initWithQueryCommand:queryCommand]; [[queryCommand addColumn:@"migration1_0" columnInfo:@"TEXT" tableName:testTable.tableName] executeWithError:error]; [testTable findWithPrimaryKey:@(1) error:NULL]; }
- (void)goDownWithQueryCommand:(CTPersistanceQueryCommand *)queryCommand error:(NSError *__autoreleasing *)error { } @end
知识点
1)
#define NSDictionaryOfVariableBindings(...)
_NSDictionaryOfVariableBindings(@"" # __VA_ARGS__, __VA_ARGS__, nil)
UIKIT_EXTERN NSDictionary *_NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, __nullable id firstValue, ...) NS_AVAILABLE_IOS(6_0); // not for direct use
NSString *name = @"wenjing";
NSNumber *age = @31; NSDictionary *dic = NSDictionaryOfVariableBindings(name, age);
(lldb) po dic { age = 31; name = wenjing; }
nice code sample
1)简单的线程间同步机制(性能应该不高,特别是,不能在主线程中执行)
- (void)performAsyncAction:(void (^)(void))action shouldWaitUntilDone:(BOOL)shouldWaitUntilDone { __block volatile BOOL shouldWait = shouldWaitUntilDone; NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ action(); shouldWait = NO; }]; [self.operationQueue addOperation:operation]; while (shouldWait) { } }
2)sqlite C语言接口使用范例
3)让类遵守协议,而不在基类里使用空方法
@interface CTPersistanceTable ()@property (nonatomic, weak) id
@end
这里为什么要一个child,而不是直接使用self?