程序正在运行,没有问题 我可以看到数据库被打开了 当我向应用添加项目时,它会在 UITableView
中显示为 NULL我有测试每个动作的单元测试:创建,更新,删除和计数 这些全部通过
以下是我的单元测试:
- (void)testToDoItemSQLite {
NSLog(@" ");
NSLog(@"*** Starting testToDoItemSQLite ***");
ToDoItemSvcSQLite *todoitemSvc = [[ToDoItemSvcSQLite alloc] init];
ToDoItem *todoitem = [[ToDoItem alloc] init];
todoitem.itemname = @"This was created by a unit test";
[todoitemSvc createToDoItem:todoitem];
NSMutableArray *todoitems = [todoitemSvc retrieveAllToDoItems];
NSLog(@"*** number of todoitems: %lu", (unsigned long)todoitems.count);
todoitem.itemname = @"This was created by a unit test";
[todoitemSvc updateToDoItem:todoitem];
[todoitemSvc deleteToDoItem:todoitem];
NSLog(@"*** Ending testToDoItemSQLite ***");
NSLog(@" ");
}
这是创建,检索,更新和删除代码
#import "ToDoItemSvcSQLite.h"
#import "sqlite3.h"
@implementation ToDoItemSvcSQLite
NSString *databasePath = nil;
sqlite3 *database = nil;
- (id)init {
if ((self = [super init])) {
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:@"todoitem.sqlite3"];
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSLog(@"database is open");
NSLog(@"database file path: %@", databasePath);
NSString *createSql = @"Create table if not exists todoitem (id integer primary key autoincrement, itemname varchar(200))";
char *errMsg;
if (sqlite3_exec(database, [createSql UTF8String], NULL, NULL, &errMsg) !=SQLITE_OK) {
NSLog(@"Failed to create table %s", errMsg);
}
}
else {
NSLog(@"*** Failed to open database!");
NSLog(@"*** SQL error: %s\n", sqlite3_errmsg(database));
}
}
return self;
}
- (ToDoItem *) createToDoItem:(ToDoItem *)todoitem {
sqlite3_stmt *statement;
NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO todoitem (itemname) VALUES (\"%@\")", todoitem.itemname];
if (sqlite3_prepare(database, [insertSQL UTF8String], -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE) {
todoitem.itemID = sqlite3_last_insert_rowid(database);
NSLog(@"ToDoItem added");
}
else {
NSLog(@"*** ToDoItem NOT added");
NSLog(@"*** SQL error: %s\n", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
return todoitem;
}
- (NSMutableArray *) retrieveAllToDoItems {
NSMutableArray *todoitems = [NSMutableArray array];
NSString *selectSQL = [NSString stringWithFormat:@"SELECT * FROM todoitem ORDER BY itemname"];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [selectSQL UTF8String], -1, &statement, NULL) == SQLITE_OK) {
NSLog(@"*** ToDoItems retrieved");
while (sqlite3_step(statement) == SQLITE_ROW) {
int id = sqlite3_column_int(statement, 0);
char *itemnameChars = (char *)sqlite3_column_text(statement, 1);
ToDoItem *todoitem = [[ToDoItem alloc] init];
todoitem.itemID = id;
todoitem.itemname = [[NSString alloc] initWithUTF8String:itemnameChars];
[todoitems addObject:todoitem];
}
sqlite3_finalize(statement);
}
else {
NSLog(@"*** ToDoItems NOT retrieved");
NSLog(@"*** SQL error %s\n", sqlite3_errmsg(database));
}
return todoitems;
}
- (ToDoItem *) updateToDoItem:(ToDoItem *)todoitem {
NSString *updateSQL = [NSString stringWithFormat: @"UPDATE todoitem SET itemname=\"%@\" WHERE id = %li ", todoitem.itemname, (long)todoitem.itemID];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [updateSQL UTF8String], -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE) {
NSLog(@"*** ToDoItem updated");
}
else {
NSLog(@"ToDoItem NOT updated");
NSLog(@"*** SQL error: %s\n", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
return todoitem;
}
- (ToDoItem *) deleteToDoItem:(ToDoItem *)todoitem {
NSString *deleteSQL = [NSString stringWithFormat: @"DELETE FROM todoitem WHERE id = %i",(int) todoitem.itemID];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [deleteSQL UTF8String], -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE) {
NSLog(@"*** ToDoItem deleted");
}
else {
NSLog(@"*** ToDoItem NOT deleted");
NSLog(@"*** SQL error: %s\n", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
return todoitem;
}
- (void)dealloc {
sqlite3_close(database);
}
@end
以下是执行所有操作的代码
添加商品
- (IBAction)addToDoItem:(id)sender {
[self.view endEditing:YES];
NSLog(@"saveToDoItem: Adding ToDoItem");
ToDoItem *todoitem = [[ToDoItem alloc] init];
todoitem.todoitem = _toDoItem.text;
[ToDoItemSvc createToDoItem:todoitem];
//clears text field on save
_toDoItem.text = @"";
[self.tableView reloadData];
NSLog(@"saveToDoItem: todoitem saved");
}
删除项目
- (IBAction)deleteToDoItem:(id)sender {
NSLog(@"Deleting ToDoItem");
[self.view endEditing:YES];
}
更新项目
- (IBAction)updateToDoItem:(id)sender {
NSLog(@"updatingToDoItem: Updating ToDoItem");
toDoItemObject.todoitem = toDoItem.text;
}
填充UITableView
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"toDoItemCell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
ToDoItem *toDoItem = [[ToDoItemSvc retrieveAllToDoItems]
objectAtIndex:indexPath.row];
cell.textLabel.text = [toDoItem description];
return cell;
}
我正在试图找出为什么我的价值观会得到NULL
当我查看数据库时,我实际上看不到表中的任何实体
这是否意味着它实际上没有更新?我对此感到有些困惑。
修改
我手动更新了数据库。我注意到它没有被阅读。我甚至更换了xcode显示正在阅读的数据库。仍然没有。
当使用归档运行时,它运行良好。显然不同的持久化数据方式。
修改
似乎持久化数据实际上是可行的,但出于某种原因,NULL
正在插入数据库中。我尝试编辑数据库以查看表是否会重新加载并获取编辑后的值。它似乎没有工作
已加载应用 保存新项目后 查看商品时
答案 0 :(得分:1)
todoitem.todoitem
和todoitem.itemname
的区别是什么?您可能正在使用todoitem.itemname
而不是todoitem.todoitem
:
- (IBAction)addToDoItem:(id)sender {
…
todoitem.itemname = _toDoItem.text;
[ToDoItemSvc createToDoItem:todoitem];
...
}
- (IBAction)updateToDoItem:(id)sender {
NSLog(@"updatingToDoItem: Updating ToDoItem");
toDoItemObject.itemname = toDoItem.text;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
ToDoItem *toDoItem = [[ToDoItemSvc retrieveAllToDoItems]
objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.itemname;
return cell;
}
希望这会对你有帮助!
修改强>
<强> ViewController.m 强>
- (IBAction)addToDoItem:(id)sender {
[self.view endEditing:YES];
NSLog(@"saveToDoItem: Adding ToDoItem");
ToDoItem *todoitem = [[ToDoItem alloc] init];
todoitem.itemname = _toDoItem.text; // I edited
[ToDoItemSvc createToDoItem:todoitem];
//clears text field on save
_toDoItem.text = @"";
[self.tableView reloadData];
NSLog(@"saveToDoItem: todoitem saved");
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"toDoItemCell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
ToDoItem *toDoItem = [[ToDoItemSvc retrieveAllToDoItems]
objectAtIndex:indexPath.row];
cell.textLabel.text = [toDoItem itemname]; // I edited
return cell;
}
<强> SecondViewController.m 强>
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
toDoItem.text = toDoItemObject.itemname; // I edited
}
<强> ToDoItemSvcSQLite.m 强>
- (ToDoItem *) updateToDoItem:(ToDoItem *)todoitem {
NSString *updateSQL = [NSString stringWithFormat: @"UPDATE todoitem SET itemname=\"%@\" WHERE id = %i ", todoitem.itemname, todoitem.id]; // I edited
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [updateSQL UTF8String], -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE) {
NSLog(@"*** ToDoItem updated");
} else {
NSLog(@"ToDoItem NOT updated");
NSLog(@"*** SQL error: %s\n", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
return todoitem;
}
最后,您应该使用init
而不是ToDoItemSvcSQLite
内的initialize
:
// ToDoItemSvcSQLite.m
static sqlite3 *database = nil;
+ (void)initialize {
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:@"todoitem"];
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSLog(@"database is open");
NSLog(@"database file path: %@", databasePath);
NSString *createSql = @"Create table if not exists todoitem (id integer primary key autoincrement, itemname varchar(200))";
char *errMsg;
if (sqlite3_exec(database, [createSql UTF8String], NULL, NULL, &errMsg) !=SQLITE_OK) {
NSLog(@"Failed to create table %s", errMsg);
}
} else {
NSLog(@"*** Failed to open database!");
NSLog(@"*** SQL error: %s\n", sqlite3_errmsg(database));
}
}
并在dealloc
内注释此行:
- (void)dealloc {
// sqlite3_close(database);
}
再次编辑:
您似乎更改了identifier
:
您应该使用viewToDoItem
:
if ([segue.identifier isEqualToString:@"viewToDoItem"]) {
然后:
// SecondViewController.m
#import "ToDoItemSvcSQLite.h"
- (IBAction)updateToDoItem:(id)sender {
NSLog(@"updatingToDoItem: Updating ToDoItem");
toDoItemObject.itemname = toDoItem.text;
[[ToDoItemSvcSQLite new] updateToDoItem:toDoItemObject];
}