开发者

How to bind indexPath.row to primary key in iphone sqlite

I can successfully update my sqlite database however I would like the primary key to correspond to the row selected in ta开发者_Go百科bleview. 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!!!


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 ... }


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜