为啥将整数插入 SQLite 会爆炸?
Posted
技术标签:
【中文标题】为啥将整数插入 SQLite 会爆炸?【英文标题】:Why inserting an Integer into SQLite would bomb out?为什么将整数插入 SQLite 会爆炸? 【发布时间】:2012-01-26 20:01:24 【问题描述】:我使用 FMDB executeUpdate 在下面的插入语句中获得了 EXC_BAD_ACCESS。它发生在 FMDatabase 中的 bindObject toColumn 上。
在 NSlog 语句中,我得到了正确的值,但更新语句被炸毁了。不知道我在这里做错了什么。
- (void) addSubject
DrillDownAppAppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
FMDatabase *database = [FMDatabase databaseWithPath:appDelegate.getDBPath];
[database open];
NSLog(@"SUBJECT_ID/TITLE/CATEGORY_TITLE = %d / %@ / %@", self.subject_id, self.title, self.category_title);
[database executeUpdate:@"insert into SUBJECT (subject_id, subject, category) values(?, ?, ?)",
self.subject_id, self.title, self.category_title, nil];
[database close];
我浏览了 FMDatabase 代码,它看起来像第一个变量,subject_id 是爆炸的那个。我尝试同时保存为 NSInteger 和 NSNumber 并且都给出了同样的崩溃。
FMDatabase 中崩溃的确切行是:
else if ([obj isKindOfClass:[NSData class]])
并且它将 subject_id 作为 NSInteger(或 NSNumber)传递并给出错误。
【问题讨论】:
【参考方案1】:FMDB executeUpdate 语句要求您使用 NSNumber 而不是 NSInteger,因此将您的 NSInteger 转换为 NSNumber 作为 executeUpdate 语句的一部分,它将起作用。我花了几个小时寻找这个,终于找到了。
这是一个外观示例:
[database executeUpdate:@"update Subject Set subject = ?, category = ? where subject_id = ?", self.title, self.category_title, [NSNumber numberWithInt:self.subject_id]];
【讨论】:
NSNumber 是一个“id”值,而 NSInteger 不是?NSNumber
是一个表示任何类型数字的 Objective-C 类。它继承自NSValue
,后者继承自NSObject
。另一方面,NSInteger
和 NSUInteger
是原始类型。这些不是 Objective-C 对象,因此它们不能转换为 id
。接受可变数量参数的 Objective-C 方法无法检查它们接收的参数的类型;这就是为什么它在编译时工作但在运行时崩溃的原因。
作为一般规则,非指针类型的变量(请注意,您需要 NSNumber*
,但您可以使用不带星号的 NSInteger
)很少 C 对象。 “异常”是 Core Foundation 对象,例如 CFStringRef
等,但这只是因为指针部分隐藏在 typedef
声明中。以上是关于为啥将整数插入 SQLite 会爆炸?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在sqlite数据库中插入数据后罗列列中没有自动增长码自动增长码是空的