Как привязать indexPath.row к первичному ключу в iphone sqlite

#iphone #objective-c #sqlite #uitableview #nsindexpath

#iPhone #objective-c #sqlite #uitableview #nsindexpath

Вопрос:

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

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

Комментарии:

1. слишком много кода = длинный и сложный вопрос, который прочтут лишь несколько человек…

Ответ №1:

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

Разделите ваш ‘performSelector’ на части и передайте каждому для выполнения индекс, вот так:

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

И повторно объявить dehydrate как:

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

Комментарии:

1. Для каждой задачи необходимо обновить PK соответствующим indexpath.row, если это имеет смысл? Просто не уверен, как соединить все это вместе, т. Е. получить indexpath.row или тег из Rootview в метод update в классе Todo! Спасибо.

2. Я пробовал это, но он выходит из строя по причине: ‘-[Todo dehydrate:]: нераспознанный селектор, отправленный экземпляру.

3. «нераспознанный селектор» означает, что вы вызываете метод с сигнатурой, отличной от сигнатуры, с которой объявлен метод (или не объявленной вообще). Вы передаете dehydrate значение int? Объявлена ли сигнатура метода с помощью int в файле .h?

4. Я не передавал ему значение int, однако вы предложили сделать это выше. В любом случае это приводит к сбою! .h — это: @property (неатомный, сохранить) Todo * задача;

Ответ №2:

Несколько замечаний о вашем коде :

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

О вашем вопросе :

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

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

Комментарии:

1. Привет, спасибо за предложения. Я согласен с вами относительно сложности, однако это был учебник, который я расширяю, и я не уверен, как сделать его менее сложным. Что касается тегов, у меня есть: [accessoryButton setTag:indexPath.row]; но я не уверен, как его получить. Еще раз спасибо.

2. глядя на ваши вопросы и комментарии, возможно, вам следует начать с нескольких более простых примеров… вы можете получить свой тег из sender.tag…