美文网首页iOS进阶之fmdb
关于fmdb(2.7)的一切,从未如此清晰

关于fmdb(2.7)的一切,从未如此清晰

作者: 天蓬大元 | 来源:发表于2018-12-04 11:14 被阅读2次
本文使用第一人称,采用fmdb自述的方式,将有关fmdb的一些常用API和实现原理一一道来。请放心,简短精准的描述下,你无需担心阅读时长。
先奉上官方权威文档:

FMDB Reference

SQLite Home Page

英语过4级的同学强烈建议去阅读官方的文档,原汁原味!!!

One section:fmdb Introduction

hello,everybody!I am fmdb. Welcome to my share party.I don't like speech because I am a shy boy. The way of share I like is you ask and I answer.So,when I speech then if you have some questions please let me know when I end .OK?
OK.But first let's see some images about me .Believe me.It's better for you to look them before listen
headFileConnection.jpg FMDBheadFile.png
FMDatabaseAdditions.jpg FMDatabaseQueue.png FMDatabasePool.png FMResultSet.png

wow,so many!!Today is a good day!!OK.Don't worry, you just need less 1/5 to finish your job.

Tow section:fmdb basic use

OK ,Here have a good example about me # LGDatabaseCacheProgram
Before you begin ,you should consideration one important thing --'thread safe' .There is a sentence from FMDatabase--'Do not instantiate a single FMDatabase object and use it across multiple threads. Instead, use <FMDatabaseQueue>.'
So,if you need add a table from db, you should use following method
NSArray*paths=NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
NSString*path=[paths objectAtIndex:0];
NSString*db = [path stringByAppendingPathComponent:CACHEUSER];
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:db];
If you don't know Sandbox,this article will help you iOS沙盒之基本概念.
Next, you can use this queue to finish add delete and change
But,don't anxious.we should first know what is FMDatabaseQueue
To perform queries and updates on multiple threads, you'll want to use `FMDatabaseQueue`.
Using a single instance of `<FMDatabase>` from multiple threads at once is a bad idea.  It has always been OK to make a `<FMDatabase>` object *per thread*.  Just don't share a single instance across threads, and definitely not across multiple threads at the same time.
First, make your queue.
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
Then use it like so:
[queue inDatabase:^(FMDatabase *db) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
    FMResultSet *rs = [db executeQuery:@"select * from foo"];
    while ([rs next]) {
        //…
    }
}];
An easy way to wrap things up in a transaction can be done like this:
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
    if (whoopsSomethingWrongHappened) {
        *rollback = YES;
        return;
    }
    // etc…
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];
`FMDatabaseQueue` will run the blocks on a serialized[ˈsɪəri:əˌlaɪzd] queue (hence the name of the class).  
So if you call `FMDatabaseQueue`'s methods from multiple[ˈməltəpəl] threads at the same time, they will be executed [ˈeksikju:tid] in the order they are received.  
This way queries and updates won't step on each other's toes, and every one is happy

Initialization

I will give you some convenient method for get a object about me.But actually,they all depend one method。
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName {
  self = [super init];
  if (self != nil) {
  /**
      [self class]:获取类名,你应该思考一下这么写的用意!!!
      [[self class] databaseClass] :获取FMDatabase或者其子类。
(databaseClass ==>返回'FMDatabase'子类,它将用于实例化数据库对象。子类可以重写此方法以返回指定的“FMDatabase”子类。)
  */
  _db = [[[self class] databaseClass] databaseWithPath:aPath];
  /**
      宏,用来兼容ARC和MRC。这里,你应该看一下这个宏的定义
  */
  FMDBRetain(_db);
    
#if SQLITE_VERSION_NUMBER >= 3005000
    BOOL success = [_db openWithFlags:openFlags vfs:vfsName];
#else
    BOOL success = [_db open];
#endif
    /**
        对数据库打开结果做了判断。。。
    */
    if (!success) {
        NSLog(@"Could not create database queue for path %@", aPath);
        FMDBRelease(self);
        return 0x00;
    }
    /**
        友情提示:如果你还不知道MRC,其先百度!!
    */
    _path = FMDBReturnRetained(aPath);
    /**创建一个队列
            dispatch_queue_t dispatch_queue_create(const char *_Nullable label,dispatch_queue_attr_t _Nullable attr);
       参数:const char *_Nullable label:label表示该队列的唯一标识字符串
            dispatch_queue_attr_t _Nullable attr:DISPATCH_QUEUE_SERIAL        //指定串行(FIFO)队列,等同于传入参数NULL
                                                 DISPATCH_QUEUE_CONCURRENT    //指定并发队列,
     */
    ///串行队列来管理任务
    _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
    /**
     dispatch_queue_set_specific就是向指定队列里面设置一个标识 如:
        dispatch_queue_set_specific(queue1, queueKey1, &queueKey1,NULL);就是向queue1对了中设置一个queueKey1标识。
     dispatch_get_specific就是在当前队列中取出标识,注意iOS中线程和队列的关系,所有的动作都是在队列中执行的!
     */
    ///添加此标记用来防止串行队列常见的死锁问题
    dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL);
    /**
         面试常见提问:深拷贝和浅拷贝
    */
    _openFlags = openFlags;
    _vfsName = [vfsName copy];
    }
    return self;
}

相关文章

  • 关于fmdb(2.7)的一切,从未如此清晰

    本文使用第一人称,采用fmdb自述的方式,将有关fmdb的一些常用API和实现原理一一道来。请放心,简短精准的描述...

  • 关于Runtime的一切,从未如此清晰

    https://immanito.github.io/2016/12/26/Runtime笔记(官方Doc翻译+原创)/

  • 从未如此清晰明了

    在我右眼上演的一幕幕默剧,却是一个无远弗届,直到——我的瞳孔逐渐放大,看到另一个瞳孔中的自己,那一刻,从未如此清晰...

  • 开发,从未如此清晰

    关于开发,我们已经有了太多的方法论和工具,这之间其实很难说哪个方法论是正确的,哪个工具是最好用的;其实开发是“任性...

  • 常用第三方框架

    FMDB 数据库插件 SWTableViewCell FMDB v2.7 数据库第三方类 JGProgressHU...

  • 祝好

    一片叶子, 在深秋的夜里陷落。 裹挟着一切的黑夜, 如此热闹, 可又分明清晰听到她的哭泣。 或许, 从未如此失落过...

  • 我从未如此清晰地感受离开

    01. 近日在读史铁生的散文集《活着的事》,零零散散,在时间的缝隙里听这位坐在轮椅上的智者絮叨(史铁生1972年双...

  • Kotlin 高阶函数从未如此清晰(中)

    前言 高阶函数系列文章: Kotlin 高阶函数从未如此清晰(上)[https://www.jianshu.com...

  • Kotlin 高阶函数从未如此清晰(中)

    前言 上篇讲到了Kotlin 高阶函数定义以及如何使用Lambda进行简化调用,本篇接着来分析未尽事项。通过本篇文...

  • Kotlin 高阶函数从未如此清晰(上)

    前言 上一篇罗列过Kotlin的属性与函数的基本知识,算是入门篇本。本篇将继续对函数的一些高级用法进行深入分析。通...

网友评论

    本文标题:关于fmdb(2.7)的一切,从未如此清晰

    本文链接:https://www.haomeiwen.com/subject/iskmcqtx.html