【问题标题】:How to bind indexPath.row to primary key in iphone sqlite如何将 indexPath.row 绑定到 iphone sqlite 中的主键
【发布时间】:2011-08-06 13:36:54
【问题描述】:

我可以成功更新我的 sqlite 数据库,但是我希望主键对应于 tableview 中选择的行。我苦苦挣扎的原因是因为我需要从 tableview 获取 indexpath 并将其传递给我更新数据库的 Todo 类。代码如下:

表视图(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)];
} 

待办事项类:

- (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");
}       
}

非常感谢!!!

【问题讨论】:

  • 太多代码 = 只有少数人会阅读的冗长而复杂的问题...

标签: iphone objective-c sqlite uitableview nsindexpath


【解决方案1】:

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

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

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

并重新声明脱水为:

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

【讨论】:

  • 每个待办事项都需要用相应的 indexpath.row 更新 PK 是否有意义?只是不知道如何将它们连接在一起,即从 Rootview 获取 indexpath.row 或标签到 Todo 类的更新方法中!谢谢。
  • 我已经尝试过了,但它崩溃的原因是:'-[Todo dehydrate:]: unrecognized selector sent to instance.
  • “无法识别的选择器”表示您调用的方法的签名与声明该方法的签名不同(或根本未声明)。您是否正在通过脱水 int ?方法签名是否在 .h 文件中用 int 声明?
  • 我没有将它传递给 int,但是您建议在上面这样做。无论哪种方式都会崩溃! .h 是:@property (nonatomic, retain) Todo *todo;
【解决方案2】:

关于您的代码的一些评论:

  1. 不应使用 AppDelegate 来托管 全局 数据,而应使用单例类
  2. 使用 [appDelegate.todos makeObjectsPerformSelector:@selector(dehydrate)];看你想做的事情太复杂了。 dehydrate 通过 pk 来定位 todo 的方法会更好。

关于你的问题:

如果 indexPath 行和 pk 之间没有对应关系,您的 Cell 应该托管主键/待办事项数据,以便您“链接”它们。

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

【讨论】:

  • 您好,感谢您的建议。关于复杂性,我同意你的看法,但是这是我正在扩展的教程,我不确定如何使它不那么复杂。关于标记,我有: [accessoryButton setTag:indexPath.row];但我不知道如何检索它。再次感谢。
  • 查看您的问题和 cmets,也许您应该从一些更简单的示例开始...您可以从 sender.tag 中检索您的标签...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
  • 2014-08-09
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
相关资源
最近更新 更多