2020年3月

SQLite使用总结

使用的库 FMDB

创建数据库

//数据库的路径
NSString *path = [NSString stringWithFormat:@"%@/Documents/DB.sqlite",NSHomeDirectory()];
//创建数据库
self.database = [[FMDatabase alloc] initWithPath:path];

if (self.database.open == NO) {
    NSLog(@"失败");
    
    return ;
}
NSLog(@"成功");

创建表

NSString *createSQL = [NSString stringWithFormat:@"create table if not exists %@ (id varchar(32), type int(11), create_time int(11))", kTableName];

BOOL status = [self.database executeUpdate:createSQL];
NSLog(@"status: %@", @(status));

新增数据

NSString *sql = [NSString stringWithFormat:@"insert into %@(id,type,create_time) values(?,?,?)", kTableName];
BOOL status = [_database executeUpdate:sql,@(myId),@(type), @(time)];

查询数据

NSString *sql = [NSString stringWithFormat:@"select * from %@ where id = %@", kTableName, @(myId)];
FMResultSet *set = [self.database executeQuery:sql];
while ([set next]) {
    model.myId = [set stringForColumn:@"id"];
    model.type = [set intForColumn:@"type"];
    model.createTime = [set intForColumn:@"create_time"];
    
    [resultList addObject:model];
}

更新数据

NSString *sql = [NSString stringWithFormat:@"update %@ set create_time = %@ where id = %@", kTableName, @(time), @(myId)];
BOOL status = [_database executeUpdate:sql];

删除数据

NSInteger expireTime = [NSDate timeStamp] - 60 * 60 * 24 * 30;
NSString *sql = [NSString stringWithFormat:@"delete from %@ where create_time > %@", kTableName, @(expireTime)];
BOOL status = [self.database executeUpdate:sql];

通过命令行管理数据

打开 Terminal
sqlite3 filename; 

// 查看帮助
.help
// 查看所有数据库
.databases
// 查看所有表
.tables
// 显示/隐藏 查询结果表头
.headers on|off
// 显示数据操作历史记录
.dump
// 将查询结果导出为Excel
.excel
// 以什么格式显示,推荐 column 格式显示
.mode list|line|column
// 查看配置
.show
// 退出
.quit

// 更多命令查看帮助文档...

修改数据失败问题处理

错误: attempt to write a readonly database

原因:sqlite3所在的文件夹没有读写权限,或者权限不足

解决办法:

  • 普通用户的话提升文件夹的权限
chmod 777 db.sqlite3
cd ..
chmod 777  *
  • 将项目移动到有全部权限的文件夹下启动

Link: Mac终端查看sqlite3数据库、表数据等(含sqlite可视化工具下载)

OC调用私有方法

OC调用私有方法共有以下四种方式:

以Person类为例:
#import "Person.h"
@implementation Person
- (void)privateMethod
{
    NSLog(@"privateMethod");
}
@end

一、分类

#import "Person.h"
NS_ASSUME_NONNULL_BEGIN
@interface Person (Test)
//只有声明,没有实现
- (void)privateMethod;
@end
NS_ASSUME_NONNULL_END

调用方式如下:

Person *person = [[Person alloc] init];
[person privateMethod];

二、performSelector

调用方式如下:

Person *person = [[Person alloc] init];
[person performSelector:@selector(privateMethod) withObject:nil];

三、objc_msgSend

调用方式如下:

Person *person = [[Person alloc] init];
objc_msgSend(person,@selector(privateMethod));

四、IMP

调用方式如下:

Person *person = [[Person alloc] init];
IMP imp = [person methodForSelector:@selector(privateMethod)];
    void (* tempFunc)(id target, SEL) = (void *)imp;
    tempFunc(person, @selector(privateMethod));

Link: OC调用私有方法