這個(gè)庫(kù)是在Casa老師在[《OS應(yīng)用架構(gòu)談 本地持久化方案及動(dòng)態(tài)部署》]這篇文章(http://casatwy.com/iosying-yong-jia-gou-tan-ben-di-chi-jiu-hua-fang-an-ji-dong-tai-bu-shu.html)里給出一個(gè)持久化方案的實(shí)現(xiàn)娄涩,比起Key Value的簡(jiǎn)單存儲(chǔ)翅帜,這個(gè)庫(kù)基于SQLite惭每,提供了對(duì)弱業(yè)務(wù)(數(shù)據(jù)操作)封裝,非常適用于有狀態(tài)的數(shù)據(jù)持久化。我上個(gè)月調(diào)查了幾種key value的持久化方式烦味,也再次看了這個(gè)方案苍凛。對(duì)我們只需要key-value存儲(chǔ)的應(yīng)用來(lái)說(shuō),這個(gè)持久化方案顯得重型了一點(diǎn)粮彤。我也是草草看了兩遍源碼根穷,沒(méi)有具體整理。最有效的學(xué)習(xí)方式還是使用并修改源碼导坟。
對(duì)這個(gè)方案里的屿良,強(qiáng)業(yè)務(wù)弱業(yè)務(wù)的分離,數(shù)據(jù)表達(dá)和數(shù)據(jù)操作的分離有點(diǎn)明白惫周,但是沒(méi)在項(xiàng)目里用上尘惧,也就沒(méi)有什么特別的心得。以后應(yīng)該還會(huì)回到這里递递,接下來(lái)會(huì)把精力方案單元測(cè)試和網(wǎng)絡(luò)的項(xiàng)目?jī)?nèi)容喷橙。
我覺(jué)得作者Tian Wei Yu (AKA: Casa Taloyum),是我的榜樣登舞。技術(shù)好贰逾,文章寫得也好,還非常熱心逊躁,基本上是有問(wèn)必答似踱,他的博客上有常常的回復(fù)列表。在這浮躁的技術(shù)界實(shí)在是少見(jiàn)稽煤。我通讀了他iOS應(yīng)用架構(gòu)談的幾篇文章核芽,受益匪淺,值得好好研究酵熙。
問(wèn)題
1)CTPersistanceTable的 isFromMigration屬性怎么使用轧简,數(shù)據(jù)庫(kù)遷移的時(shí)候要注意些什么?
2)CTPersistanceQueryCommand.m line 72 如果傳進(jìn)來(lái)的error為nil匾二,函數(shù)調(diào)用失敗返回YES哮独,而不是NO
總結(jié)
1)版本遷移的步驟
在創(chuàng)建數(shù)據(jù)庫(kù)對(duì)象時(shí),判斷是否需要遷移察藐,并執(zhí)行遷移皮璧。具體是在 CTPersistanceDataBase 類的 - (instancetype)initWithDatabaseName:(NSString *)databaseName error:(NSError *__autoreleasing *)error 方法。
數(shù)據(jù)庫(kù)中有一張叫做 CTPersistanceVersionTable的表分飞,記錄當(dāng)前的數(shù)據(jù)庫(kù)版本悴务。表只有2個(gè)字段,一條記錄。如果表中無(wú)記錄讯檐,用 CTPersistanceMigrator的 migrationVersionList第一條記錄初始化它羡疗。
+ (NSDictionary *)columnInfo{ return @{ @"identifier":@"INTEGER PRIMARY KEY AUTOINCREMENT", @"databaseVersion":@"TEXT" }; }
一個(gè)數(shù)據(jù)庫(kù)對(duì)應(yīng)一個(gè)Migrator,Migrator的migrationVersionList别洪,記錄數(shù)據(jù)庫(kù)的遷移的所有版本叨恨。每個(gè)版本對(duì)應(yīng)一個(gè)遵守 CTPersistanceMigrationStep協(xié)議的MigrationStep類,這個(gè)類里提供了對(duì)應(yīng)版本的向上和向下遷移的方法挖垛。
@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
知識(shí)點(diǎn)
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)簡(jiǎn)單的線程間同步機(jī)制(性能應(yīng)該不高痒钝,特別是,不能在主線程中執(zhí)行)
- (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語(yǔ)言接口使用范例
3)讓類遵守協(xié)議晕换,而不在基類里使用空方法
@interface CTPersistanceTable ()@property (nonatomic, weak) id<CTPersistanceTableProtocol> child;@property (nonatomic, strong, readwrite) CTPersistanceQueryCommand *queryCommand;
@end
這里為什么要一個(gè)child午乓,而不是直接使用self?