Как привязать indexPath.row к первичному ключу в iphone sqlite - PullRequest
0 голосов
/ 15 апреля 2011

Я могу успешно обновить свою базу данных sqlite, однако мне бы хотелось, чтобы первичный ключ соответствовал строке, выбранной в табличном представлении.Причина, по которой я борюсь, заключается в том, что мне нужно получить indexpath из таблицы и передать его моему классу 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");
}       
}

Большое спасибо !!!

Ответы [ 2 ]

0 голосов
/ 15 апреля 2011

Некоторые замечания о вашем коде:

  1. Вместо использования AppDelegate для размещения глобальных данных, вы должны использовать одноэлементный класс
  2. с помощью [appDelegate.todosmakeObjectsPerformSelector: @selector (обезвоживают)];Слишком сложно смотреть на то, что вы хотите сделать.dehydrate метод, нацеливающий задачу на pk, был бы лучше.

По поводу вашего вопроса:

Ваша ячейка должна содержать данные первичного ключа / задачи, чтобы вы могли "связать" ихесли нет соответствия между строкой indexPath и pk.

Один простой способ, если вы не хотите создавать свой собственный подкласс ячейки, - это использовать cell tag свойство

0 голосов
/ 15 апреля 2011

Я должен предположить из вашего кода, что каждый из задач получит один и тот же PK (indexPath.row).

Разбейте свой 'executeSelector' на части и передайте каждому индекс индекс, например:

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

И повторно объявить обезвоживание как:

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