转载自: https://blog.youkuaiyun.com/Axing1991/article/details/51925382
FMDB误用引起的,解决后记录一下:
值为null的列处理
先是通过resultDictionary方法,将ResultSet转换成NSDictionary
|
1
2
3
4
|
FMResultSet *rs = [db executeQuery:sql];
while([rs next]) {
[result addObject:[rs resultDictionary]];
}
|
然后用objectForKey取出某一列的值,如果该列为空,则返回NSNull,但是判断非空时发生错误:
|
1
2
3
4
|
NSString* originFilePath = [row objectForKey:columnName];// 原始文件路径
if(originFilePath){
// 非空处理
}
|
上面的代码是错的,即使此列为空,也会走进非空的分支。要用下面的代码:
|
1
2
3
4
|
NSString* originFilePath = [row objectForKey:columnName];// 原始文件路径
if((NSNull *)originFilePath != [NSNull null]){
// 非空处理
}
|
拼接SQL时,表名不能是变量
做一个简单的全表查询,返回结果居然是0 row,最后发现表名不能是变量,以下2种写法都是错的
|
1
|
FMResultSet *rs = [db executeQuery:@"select * from %@", tableName];
|
|
1
|
FMResultSet *rs = [db executeQuery:@"select * from ?", tableName];
|
查询参数可以是变量,然后绑定参数,但是表名必须是常量,所以要这么写:
|
1
2
|
NSString *sql = [NSString stringWithFormat:@"select * from %@", tableName];
FMResultSet *rs = [db executeQuery:sql];
|
先提前把sql拼好,传给executeQuery方法的是一个常量
传给executeQuery或者executeUpdate的参数,必须是NSObject
执行一句SQL时,FMDB报EXC_BAD_ACCESS,应用崩溃。在stackoverflow上查到,传给execute方法的参数,必须是NSObject。如果本来是原始数据类型如int,long等,要先用Wrapper类包装一下。以下的代码是错的:
|
1
|
FMResultSet *rs = [db executeQuery:sql, latestBackupTime, now];// latestBackupTime和now是long类型,造成EXC_BAD_ACCESS
|
应该写成:
|
1
2
3
|
longnow = [[NSDate date] timeIntervalSince1970];
// 传给executeQuery()的参数必须是NSObject,不能是原始数据类型,否则报EXC_BAD_ACCESS
FMResultSet *rs = [db executeQuery:sql, [NSNumber numberWithLong:latestBackupTime], [NSNumber numberWithLong:now]];
|
本文探讨了FMDB中处理NULL值的正确方法,避免表名变量化导致的问题,并介绍了如何正确传递参数以防止EXC_BAD_ACCESS异常。
2413

被折叠的 条评论
为什么被折叠?



