该文件是对对象类型进行encoding 以及 decoding操作的方法
1. 该文件是 sqlite3 单例数据库对Model 对象进行增.删.查.改
1. 而Model文件夹下面的TestModel 则是继承自Model 的一种自定义model (也就是我们项目中的自定义的Model),
2.如此,我们自己项目中的自定义model 只要继承字Model 类就可以了,
3.但还要在自定义的TestModel中添加以下改动: self.ID属性是从父类Model中继承来的 而Model 的ID属性被设置为数据库的主键, 因此不可以为空,需要将TestModel的一个属性替代ID属性,既作为主键;
.h文件
.m文件
#import "NSObject+NSCoding.h"#import <objc/runtime.h>#import <UIKit/UIKit.h>@implementation NSObject (NSCoding)- (NSMutableDictionary *)propertiesForClass:(Class)klass { NSMutableDictionary *results = [[NSMutableDictionary alloc] init]; unsigned int outCount, i; //通过运行时获取 该类所有属性列表 objc_property_t *properties = class_copyPropertyList(klass, &outCount); for(i = 0; i < outCount; i++) { objc_property_t property = properties[i]; NSString *pname = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]; NSString *pattrs = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding]; pattrs = [[pattrs componentsSeparatedByString:@","] objectAtIndex:0]; pattrs = [pattrs substringFromIndex:1]; [results setObject:pattrs forKey:pname]; } free(properties); if ([klass superclass] != [NSObject class]) { [results addEntriesFromDictionary:[self propertiesForClass:[klass superclass]]]; } return results;}- (NSDictionary *)properties { return [self propertiesForClass:[self class]];}- (void)autoEncodeWithCoder:(NSCoder *)coder { NSDictionary *properties = [self properties]; for (NSString *key in properties) { NSString *type = [properties objectForKey:key]; id value; unsigned long long ullValue; BOOL boolValue; float floatValue; double doubleValue; NSInteger intValue; unsigned long ulValue; long longValue; unsigned unsignedValue; short shortValue; NSString *className; NSMethodSignature *signature = [self methodSignatureForSelector:NSSelectorFromString(key)]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:NSSelectorFromString(key)]; [invocation setTarget:self]; switch ([type characterAtIndex:0]){ case '@': // object if ([[type componentsSeparatedByString:@"\""] count] > 1) { className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1]; Class class = NSClassFromString(className); #warning UIImage类型的属性不归档 add by yhy› if ([className isEqualToString:@"UIImage"]) { //如果属性是UIImage类型的,不进行归档 break; } #pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks" value = [self performSelector:NSSelectorFromString(key)];#pragma clang diagnostic pop // only decode if the property conforms to NSCoding if([class conformsToProtocol:@protocol(NSCoding)]){ [coder encodeObject:value forKey:key]; } } break; case 'c': // bool [invocation invoke]; [invocation getReturnValue:&boolValue]; [coder encodeObject:[NSNumber numberWithBool:boolValue] forKey:key]; break; case 'f': // float [invocation invoke]; [invocation getReturnValue:&floatValue]; [coder encodeObject:[NSNumber numberWithFloat:floatValue] forKey:key]; break; case 'd': // double [invocation invoke]; [invocation getReturnValue:&doubleValue]; [coder encodeObject:[NSNumber numberWithDouble:doubleValue] forKey:key]; break; case 'i': // int [invocation invoke]; [invocation getReturnValue:&intValue]; [coder encodeObject:[NSNumber numberWithInt:(int)intValue] forKey:key]; break; case 'L': // unsigned long [invocation invoke]; [invocation getReturnValue:&ulValue]; [coder encodeObject:[NSNumber numberWithUnsignedLong:ulValue] forKey:key]; break; case 'Q': // unsigned long long [invocation invoke]; [invocation getReturnValue:&ullValue]; [coder encodeObject:[NSNumber numberWithUnsignedLongLong:ullValue] forKey:key]; break; case 'l': // long [invocation invoke]; [invocation getReturnValue:&longValue]; [coder encodeObject:[NSNumber numberWithLong:longValue] forKey:key]; break; case 's': // short [invocation invoke]; [invocation getReturnValue:&shortValue]; [coder encodeObject:[NSNumber numberWithShort:shortValue] forKey:key]; break; case 'I': // unsigned [invocation invoke]; [invocation getReturnValue:&unsignedValue]; [coder encodeObject:[NSNumber numberWithUnsignedInt:unsignedValue] forKey:key]; break; default: break; } }}- (void)autoDecode:(NSCoder *)coder { NSDictionary *properties = [self properties]; for (NSString *key in properties) { NSString *type = [properties objectForKey:key]; id value; NSNumber *number; NSInteger i; CGFloat f; BOOL b; double d; unsigned long ul; unsigned long long ull; long longValue; unsigned unsignedValue; short shortValue; NSString *className; switch ([type characterAtIndex:0]) { case '@': // object if ([[type componentsSeparatedByString:@"\""] count] > 1) { className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1]; Class class = NSClassFromString(className); #warning UIImage类型的属性不归档 add by yhy if ([className isEqualToString:@"UIImage"]) { //如果属性是UIImage类型的,不进行反归档 break; } // only decode if the property conforms to NSCoding if ([class conformsToProtocol:@protocol(NSCoding )]){ value = [coder decodeObjectForKey:key]; [self setValue:value forKey:key]; } } break; case 'c': // bool number = [coder decodeObjectForKey:key]; b = [number boolValue]; [self setValue:@(b) forKey:key]; break; case 'f': // float number = [coder decodeObjectForKey:key]; f = [number floatValue]; [self setValue:@(f) forKey:key]; break; case 'd': // double number = [coder decodeObjectForKey:key]; d = [number doubleValue]; [self setValue:@(d) forKey:key]; break; case 'i': // int number = [coder decodeObjectForKey:key]; i = [number intValue]; [self setValue:@(i) forKey:key]; break; case 'L': // unsigned long number = [coder decodeObjectForKey:key]; ul = [number unsignedLongValue]; [self setValue:@(ul) forKey:key]; break; case 'Q': // unsigned long long number = [coder decodeObjectForKey:key]; ull = [number unsignedLongLongValue]; [self setValue:@(ull) forKey:key]; break; case 'l': // long number = [coder decodeObjectForKey:key]; longValue = [number longValue]; [self setValue:@(longValue) forKey:key]; break; case 'I': // unsigned number = [coder decodeObjectForKey:key]; unsignedValue = [number unsignedIntValue]; [self setValue:@(unsignedValue) forKey:key]; break; case 's': // short number = [coder decodeObjectForKey:key]; shortValue = [number shortValue]; [self setValue:@(shortValue) forKey:key]; break; default: break; } }}@end
.h文件
.m文件
#import <sqlite3.h>#import "DatabaseHandle.h"#import "Model.h"#define ARCHIVERKEY @"archiver"static DatabaseHandle *dataHandle =nil;@implementation DatabaseHandle+ (DatabaseHandle*)shardInstnce{ @synchronized(self){ if (dataHandle == nil) { dataHandle = [[DatabaseHandle alloc]init]; } return dataHandle; }}//打开数据库static sqlite3 *db = nil;- (void)openDB{ if (db !=nil) { return; } NSString *filePath = [self useCachesPathSqlite:@"WatchBall.sqlite"]; NSLog(@"db filePath = %@",filePath); int result = sqlite3_open(filePath.UTF8String, &db); if (result ==SQLITE_OK) { NSString *createModelSql = @"CREATE TABLE ModelList(ID TEXT PRIMARY KEY,title TEXT,imageUrl TEXT,data BLOB)"; //执行参数? sqlite3_exec(db, [createModelSql UTF8String], NULL, NULL, NULL); }}- (void)closeDB{ int result = sqlite3_close(db); if (result ==SQLITE_OK) { db = nil; NSLog(@"关闭成功"); }}//插入收藏活动- (void)insertNewactivity:(Model *)model{ [self openDB]; static sqlite3_stmt *stmt = nil; NSString *sql = @"insert into ModelList(ID,title,imageUrl,data) values (?,?,?,?)"; int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil); if (result ==SQLITE_OK) { sqlite3_bind_text(stmt, 1, [model.ID UTF8String], -1, nil); sqlite3_bind_text(stmt, 2, [model.title UTF8String], -1, nil); sqlite3_bind_text(stmt, 3, [model.imageUrl UTF8String], -1, nil); NSString *archiverKey = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,model.ID]; NSData *data = [self dataOfArchiverObject:model forKey:archiverKey]; sqlite3_bind_blob(stmt, 4, [data bytes], (int)[data length], nil); sqlite3_step(stmt); } sqlite3_finalize(stmt);}- (void)deleteModelByID:(NSString *)ID{ [self openDB]; NSString *deleteSQL = [NSString stringWithFormat:@"delete from ModelList where ID ='%@'",ID]; char * error =nil; int result = sqlite3_exec(db, deleteSQL.UTF8String, NULL, NULL, &error); if (result == SQLITE_OK) { NSLog(@"删除成功"); }else{ NSLog(@"删除失败 error = %s",error); } }- (Model*)selectModelWithID:(NSString *)ID{ [self openDB]; sqlite3_stmt *stmt = nil; NSString *sql = @"select data from ModelList where ID = ?"; int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL); Model *model = nil; if (result ==SQLITE_OK) { sqlite3_bind_text(stmt, 1, [ID UTF8String], -1, NULL); if (sqlite3_step(stmt) ==SQLITE_ROW) { NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; NSString *archiver = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,ID]; model = [self unarchiverObject:data forKey:archiver]; } } sqlite3_finalize(stmt); return model; }- (NSArray*)selectAllModel{ [self openDB]; sqlite3_stmt *stmt = nil; NSString *sql = @"select ID,data from ModelList"; int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL); NSMutableArray *activityArray = [NSMutableArray array]; if (result == SQLITE_OK) { while (sqlite3_step(stmt) ==SQLITE_ROW) { NSString *ID = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(stmt, 0)]; NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 1) length:sqlite3_column_bytes(stmt, 1)]; NSString *modelKey = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,ID]; Model * model = [self unarchiverObject:data forKey:modelKey]; [activityArray addObject:model]; NSLog(@"%@",model); } } sqlite3_finalize(stmt); if (activityArray.count ==0) { return nil; } return activityArray;}- (BOOL)isFavoriteModelWithID:(NSString *)ID{ Model *model = [self selectModelWithID:ID]; if (model ==nil) { NSLog(@"没有收藏该条目"); return NO; } NSLog(@"已经收藏"); return YES; }#pragma ---文件路径处理----文件夹路径处理- (NSString*)useCachesPathSqlite:(NSString*)databaseName{ NSString *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject; NSString *filePath = [caches stringByAppendingPathComponent:databaseName]; return filePath;}#pragma ---归档处理---- (NSData *)dataOfArchiverObject:(id)object forKey:(NSString*)key{ NSMutableData *data = [NSMutableData data]; NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data]; [archiver encodeObject:object forKey:key]; [archiver finishEncoding]; return data; }- (id)unarchiverObject:(NSData*)data forKey:(NSString *)key{ NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; id object = [unarchiver decodeObjectForKey:key]; [unarchiver finishDecoding]; return object;}@end
.h文件
.m文件
转载于:https://www.cnblogs.com/zhouyubo/p/4555754.html
