FMDB源码系列(一)

FMDB有FMDatabase、FMDatabaseQueue、FMResultSet这三个重量级的类。

  • FMDatabase
    用来表示sqlite3数据库对象。
  • FMDatabaseQueue
    用来执行线程安全的多线程数据库操作。
  • FMResultSet
    数据库对象根据sql语句进行操作后返回的结果集对象。

笔者对于FMDB源码的探究首先从这三个类入手,由于FMDatabaseQueue引用到了FMDatabase,而FMDatabase又引用到了FMResultSet。所以笔者决定通过FMResultSet -> FMDatabase -> FMDatabaseQueue这样的顺序来解读这三个类。

FMDB中用到的宏

在解读源码之前,我们先来看一下FMDB中常用到的一些宏。

  • NS_ASSUME_NONNULL_BEGIN&NS_ASSUME_NONNULL_END
    在代码中,包含在这两个宏中间的属性、方法均会被加上一个nonnull的标记。如果想要其中的属性或方法不受此约束,则在对应的属性中加入nullable即可
    我们可以点击看到这两条宏所定义的语句为
#ifndef NS_ASSUME_NONNULL_BEGIN
#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
#endif
#ifndef NS_ASSUME_NONNULL_END
#define NS_ASSUME_NONNULL_END   _Pragma("clang assume_nonnull end")
#endif

_Pragma看上去是不是很熟悉,我们经常在代码中写

#pragma mark - 自定义字符串

这是C++中的杂注指令,关于这点,可以看看这里
这意味着,我们这样写也是有效的

#pragma clang assume_nonnull begin
#pragma clang assume_nonnull end

  • FMDB_SQLITE_STANDALONE
    这个宏是在FMDB中的podspec中定义的
s.subspec 'standalone' do |ss|
    ss.xcconfig = { 'OTHER_CFLAGS' => '$(inherited) -DFMDB_SQLITE_STANDALONE' }
    ss.dependency 'sqlite3'
    ss.source_files = 'src/fmdb/FM*.{h,m}'
    ss.exclude_files = 'src/fmdb.m'
  end

目前FMDB中设定的默认子文件夹是'standard',并不是standalone或者standalone-fts。所以这个宏在工程中都返回NO。


  • OS_OBJECT_USE_OBJC
    这个宏在FMDB中用于
#if OS_OBJECT_USE_OBJC
        #define FMDBDispatchQueueRelease(__v)
    #else
        #define FMDBDispatchQueueRelease(__v) (dispatch_release(__v));
    #endif

OS_OBJECT_USE_OBJC是针对过去iOS 6.0以下版本的GCD并不具备ARC所产生的。所以当OS_OBJECT_USE_OBJC返回0时,GCD需要使用dispatch_release()来释放内存。


  • NS_RETURNS_NOT_RETAINED
    这个宏用于标注带返回值的方法,并且还有一个兄弟叫做NS_RETURNS_RETAINED。在FMDB中只有2个方法标注了这个宏,并且都在注释中写上了Warning。
- (NSData * _Nullable)dataNoCopyForColumnIndex:(int)columnIdx NS_RETURNS_NOT_RETAINED;

- (NSData * _Nullable)dataNoCopyForColumnIndex:(int)columnIdx NS_RETURNS_NOT_RETAINED;

NS_RETURNS_NOT_RETAINED表示这个方法返回的对象,不需要被release,而NS_RETURNS_RETAINED则表示方法所返回的对象需要被release。


最后在提一下__has_feature这个方法,在Clang中是这么解释的
HasFeature - Return true if we recognize and implement the feature specified by the identifier as a standard language feature.
即为:如果我们识别并实现标识符指定的功能作为标准语言功能,则返回true(google翻译,doge)。
在Clang中它定义了非常多的关键词,有兴趣的朋友可以去看看PPMacroExpansion.cpp,从1094行开始。


再贴一下FMDB中所使用的Sqlite3错误码

#define SQLITE_OK           0   /* 成功 | Successful result */
/* 错误码开始 */
#define SQLITE_ERROR        1   /* SQL错误 或 丢失数据库 | SQL error or missing database */
#define SQLITE_INTERNAL     2   /* SQLite 内部逻辑错误 | Internal logic error in SQLite */
#define SQLITE_PERM         3   /* 拒绝访问 | Access permission denied */
#define SQLITE_ABORT        4   /* 回调函数请求取消操作 | Callback routine requested an abort */
#define SQLITE_BUSY         5   /* 数据库文件被锁定 | The database file is locked */
#define SQLITE_LOCKED       6   /* 数据库中的一个表被锁定 | A table in the database is locked */
#define SQLITE_NOMEM        7   /* 某次 malloc() 函数调用失败 | A malloc() failed */
#define SQLITE_READONLY     8   /* 尝试写入一个只读数据库 | Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* 操作被 sqlite3_interupt() 函数中断 | Operation terminated by sqlite3_interrupt() */
#define SQLITE_IOERR       10   /* 发生某些磁盘 I/O 错误 | Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* 数据库磁盘映像不正确 | The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* sqlite3_file_control() 中出现未知操作数 | Unknown opcode in sqlite3_file_control() */
#define SQLITE_FULL        13   /* 因为数据库满导致插入失败 | Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* 无法打开数据库文件 | Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* 数据库锁定协议错误 | Database lock protocol error */
#define SQLITE_EMPTY       16   /* 数据库为空 | Database is empty */
#define SQLITE_SCHEMA      17   /* 数据结构发生改变 | The database schema changed */
#define SQLITE_TOOBIG      18   /* 字符串或二进制数据超过大小限制 | String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT  19   /* 由于约束违例而取消 | Abort due to constraint violation */
#define SQLITE_MISMATCH    20   /* 数据类型不匹配 | Data type mismatch */
#define SQLITE_MISUSE      21   /* 不正确的库使用 | Library used incorrectly */
#define SQLITE_NOLFS       22   /* 使用了操作系统不支持的功能 | Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* 授权失败 | Authorization denied */
#define SQLITE_FORMAT      24   /* 附加数据库格式错误 | Auxiliary database format error */
#define SQLITE_RANGE       25   /* 传递给sqlite3_bind()的第二个参数超出范围 | 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* 被打开的文件不是一个数据库文件 | File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite3_step() 已经产生一个行结果 | sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() 完成执行操作 | sqlite3_step() has finished executing */

下一篇我们将走进FMResultSet中的世界,一探究竟。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容

  • 1 FMDB简介 1.1 使用方法 首先到这裡下载FMDB的source code,接著在解开的档案裡,把src资...
    Kevin_Junbaozi阅读 1,232评论 0 1
  • FMDB v2.6.2 这是个SQLite的OC封装。SQLite的地址:http://sqlite.org/ F...
    原鸣清阅读 2,287评论 0 3
  • FMDB 1、简述: * FMDB是iOS平台的SQLite数据库框架,是对libsqlite3框架的封装 * F...
    莦婼姑娘阅读 4,462评论 9 40
  • 前言: 今天,就让我们,重点学习一下FMDB。 FMDB学习 一、基本介绍 简介:-由于iOS中原生的 SQLit...
    麦穗0615阅读 3,758评论 0 27
  • //联系人:石虎QQ: 1224614774昵称:嗡嘛呢叭咪哄 一、简单说明 1.什么是FMDB FMDB是iOS...
    石虎132阅读 2,145评论 5 13