標籤:
iOS簡單runtime封裝fmdb的使用學習了iOS有一段時間了,使用到fmdb操作資料庫的時候感覺有很多重複性的工作要做,查詢資料庫時物件導向性感覺很差,一個查詢只能針對一個Model,經過瞭解發現了runtime的使用可以解決這一問題。使用fmdb的時候相信有過這樣的經曆查詢某個model時:
NSString *sql = @"select * from myFmdb"; FMResultSet *set = [self.database executeQuery:sql]; while (set.next) { int pid = [set intForColumn:@"id"]; <span style="color:#ff0000;">NSString *name = [set stringForColumnIndex:1]; NSInteger age = [set intForColumn:@"age"];</span> NSLog(@"id==%d,name==%@,age==%ld",pid,name,age); }其中紅色的代碼是查詢的某一個欄位,我們不僅要知道欄位的類型還要知道欄位的位置,用起來就很不方便,而如果model類發生了改變那查詢語句也隨之改變才行。簡單使用runtime可解決此類問題。使用runtime代碼如下(寫成了一個方法):
- (NSMutableArray *)finAllWithSql:(NSString *)tableName fmdb:(FMDatabase *)db model:(Class)cls{ //建立要返回的數組 NSMutableArray *data = [NSMutableArray array]; //根據表明查詢資料庫 NSString *sql = [NSString stringWithFormat:@"select * from %@",tableName]; //根據第三方的FMdatabase查詢結果集 FMResultSet *set = [db executeQuery:sql]; //擷取該model類的所有的屬性列表 unsigned int count = 0; Ivar *ivars = class_copyIvarList(cls, &count); //遍曆 while ([set next]) { //根據傳進來的類cls,建立對應的對象並儲存. id obj = [[cls alloc] init]; //遍曆所有的屬性變數 for (int i=0; i<count; i++) { //得到該屬性 Ivar ivar = ivars[i]; const char *type = ivar_getTypeEncoding(ivar); //的到屬性的類型用於判斷 NSString *valueType = [NSString stringWithCString:type encoding:NSUTF8StringEncoding]; //得到屬性的name使用setKey來設定值,要把屬性那麼前面的"_"去掉. NSString *proName = [NSString stringWithCString:ivar_getName(ivar) encoding:NSUTF8StringEncoding]; NSString *name = [proName componentsSeparatedByString:@"_"][1]; //判斷屬性類型,這裡僅考慮了NSString,int和float類型(這裡吧float轉化為了double) if ([valueType hasPrefix:@"@"]) { //這是NSString類型的,設定值 [obj setValue:[set stringForColumnIndex:i] forKey:name]; }else if([valueType hasPrefix:@"q"]|[valueType hasPrefix:@"i"]){ //"q"代表的是NSInteger類型,這是NSInteger類型的,設定值 [obj setValue:@([set intForColumnIndex:i]) forKey:name]; }else if ([valueType hasPrefix:@"f"]){ //這是float類型的,設定值 [obj setValue:@([set doubleForColumnIndex:i]) forKey:name]; } } //將該字典儲存到數組中. [data addObject:obj]; } return data;}現對以上代碼進行說明,首先傳進來的參數有查詢的表名,要查詢的資料庫以及查詢的model類,使用fmdb查詢後得到查詢結果集,通過
unsigned int count = 0;Ivar *ivars = class_copyIvarList(cls, &count);
得到model類的屬性列表,然後遍曆結果集,然後遍曆屬性列表的屬性,
const char *type = ivar_getTypeEncoding(ivar);
得到的是屬性的類型,之後的幾條語句是將這個類型進行處理以用於判斷,
if語句是用於判斷屬性類型的,這裡僅僅只是展示了三種類型,把屬性值通過setValue forKey的方式複製給通過傳進來的參數
cls建立的類,然後儲存到數組中。最後返回數組。可以看出要想查詢結果只要傳進來幾個參數就行了,最後返回的數組儲存的是id類型的,用的時候強轉一下就好了。第一次寫部落格,希望方便大家學習,也方便自己學習進步,望大家指教。runtime的使用還是菜鳥,很多地方也有待改正望大神斧正。其實也可以封裝sqlite的,只是寫的時候就寫成了這個樣子。
iOS簡單runtime封裝fmdb的使用