如何将indexPath.row绑定到iphone sqlite中的主键

发布于 2024-11-01 10:26:54 字数 1870 浏览 7 评论 0原文

我可以成功更新我的 sqlite 数据库,但是我希望主键与表视图中选择的行相对应。我苦苦挣扎的原因是因为我需要从表视图获取索引路径并将其传递给我更新数据库的 Todo 类。这是代码:

Tableview (RootViewController):

- (void)updateStatus:(id)sender { // called when a user presses the button to alter the status

NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[sender superview]];
NSLog(@"The row id is %d",  indexPath.row); // This works

todoAppDelegate *appDelegate = (todoAppDelegate *)[[UIApplication sharedApplication] delegate];
Todo *td = [appDelegate.todos objectAtIndex:indexPath.row];

self.selectedIndexPath = indexPath;
NSLog(@"Selected index path is %i", self.selectedIndexPath); 

if (td.status == 0) {       
    [td updateStatus:1];
    NSLog(@"Status is %i",td.status);
}
else {
    [td updateStatus:0];
    NSLog(@"Status is %i",td.status);
}

[appDelegate.todos makeObjectsPerformSelector:@selector(dehydrate)];
} 

Todo 类:

- (void) dehydrate {
if (dirty) { // If the todo is “dirty” meaning the dirty property was set to YES, we will need to save the new data to the database.
if (dehydrate_statment == nil) {
    const char *sql = "update todo set complete = ? where pk= ?"; // PK needs to correspond to indexpath in RootViewController

    if (sqlite3_prepare_v2(database, sql, -1, &dehydrate_statment, NULL) != SQLITE_OK) {
        NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
    }
}

sqlite3_bind_int(dehydrate_statment, 2, self.primaryKey);
sqlite3_bind_int(dehydrate_statment, 1, self.status);
int success = sqlite3_step(dehydrate_statment);

if (success != SQLITE_DONE) {
    NSAssert1(0, @"Error: failed to save priority with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_reset(dehydrate_statment);
dirty = NO;
NSLog(@"Dehydrate called");
}       
}

非常感谢!

I can successfully update my sqlite database however I would like the primary key to correspond to the row selected in tableview. The reason I'm struggling is because I need to get the indexpath from the tableview and pass it to my Todo class where I update the database. Here's the code:

Tableview (RootViewController):

- (void)updateStatus:(id)sender { // called when a user presses the button to alter the status

NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[sender superview]];
NSLog(@"The row id is %d",  indexPath.row); // This works

todoAppDelegate *appDelegate = (todoAppDelegate *)[[UIApplication sharedApplication] delegate];
Todo *td = [appDelegate.todos objectAtIndex:indexPath.row];

self.selectedIndexPath = indexPath;
NSLog(@"Selected index path is %i", self.selectedIndexPath); 

if (td.status == 0) {       
    [td updateStatus:1];
    NSLog(@"Status is %i",td.status);
}
else {
    [td updateStatus:0];
    NSLog(@"Status is %i",td.status);
}

[appDelegate.todos makeObjectsPerformSelector:@selector(dehydrate)];
} 

Todo class:

- (void) dehydrate {
if (dirty) { // If the todo is “dirty” meaning the dirty property was set to YES, we will need to save the new data to the database.
if (dehydrate_statment == nil) {
    const char *sql = "update todo set complete = ? where pk= ?"; // PK needs to correspond to indexpath in RootViewController

    if (sqlite3_prepare_v2(database, sql, -1, &dehydrate_statment, NULL) != SQLITE_OK) {
        NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
    }
}

sqlite3_bind_int(dehydrate_statment, 2, self.primaryKey);
sqlite3_bind_int(dehydrate_statment, 1, self.status);
int success = sqlite3_step(dehydrate_statment);

if (success != SQLITE_DONE) {
    NSAssert1(0, @"Error: failed to save priority with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_reset(dehydrate_statment);
dirty = NO;
NSLog(@"Dehydrate called");
}       
}

Many thanks!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怂人 2024-11-08 10:26:54

我必须从您的代码中假设每个待办事项都会获得相同的 PK(indexPath.row)。

将“performSelector”分开,并传递每个待办事项索引,如下所示:

  for ( Todo *todo in appDelegate.todos ) {
        [todo dehydrate:indexPath.row];
   }

并将脱水重新声明为:

     - (void) dehydrate:(int) primaryKey {  // use pk here ... }

I have to assume from your code that each of the todo's will get the same PK (the indexPath.row).

Break your 'performSelector' apart, and pass each todo the index, like this:

  for ( Todo *todo in appDelegate.todos ) {
        [todo dehydrate:indexPath.row];
   }

And re-declare dehydrate as:

     - (void) dehydrate:(int) primaryKey {  // use pk here ... }
老娘不死你永远是小三 2024-11-08 10:26:54

关于代码的一些注释:

  1. 单例类,而不是使用 AppDelegate 托管全局数据。
  2. 您应该使用 [appDelegate.todos makeObjectsPerformSelector:@selector(deHydrate)]; 的 看看你想做什么就太复杂了。通过 pk 来针对待办事项的 脱水 方法会更好。

关于你的问题:

你的单元格应该托管主键/待办事项数据,以便在indexPath行和pk之间没有对应关系的情况下允许你“链接”它们。

如果您不想创建自己的单元子类,一个简单的技巧是使用 单元格 tag 属性

Some remarks about your code :

  1. Instead of using AppDelegate to host global data, you should use a singleton class
  2. using [appDelegate.todos makeObjectsPerformSelector:@selector(dehydrate)]; is over complex looking at what you want to do. A dehydrate method targeting a todo by pk would be better.

About your question :

Your Cell should host primary key / todo data for allowing you to "link" them if there is no correspondance between indexPath row and pk.

One easy trick if you don't want make your own cell subclass, is to use cell tag property

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文