iPhone SDK: загрузка UITableView из SQLite - PullRequest
1 голос
/ 12 октября 2009

Мне кажется, я хорошо разбираюсь в UITableView и в получении / вставке данных из / в базу данных SQLite. Я борюсь с архитектурным вопросом.

Мое приложение сохраняет 3 значения в базе данных, может быть много / много строк. Однако я бы загрузил их в таблицу?

Из всех обучающих программ, которые я видел, в какой-то момент вся база данных загружается в NSMutableArray или подобный объект посредством выполнения инструкции SELECT.

Тогда когда

- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath

вызывается, необходимые строки извлекаются из предыдущего загруженного NSMutableArray (или аналогичной структуры).

Но что у меня есть тысячи для строк? Зачем мне их предварительно загружать?

Должен ли я просто запрашивать базу данных каждый раз, когда вызывается cellForRowAtIndexPath? Если так, что бы я использовал в качестве индекса?

Каждая строка в таблице будет иметь индекс AUTOINCREMENT, но поскольку некоторые строки могут быть удалены, индекс не будет соответствовать строкам в таблице (в SQL я могу иметь что-то подобное со строкой с отсутствующим индексом 3):

1 Данные1 Данные1 2 Данные2 Данные2 4. data3 data3

Спасибо

Ответы [ 3 ]

3 голосов
/ 12 октября 2009

Я решаю эту проблему, читая, что нужно ячейке таблицы из моей базы данных в массив источника данных, из всех существующих записей базы данных. Однако объекты не удаляются из массива, они остаются там, если их не нужно удалять.

Например, одно из моих приложений читает 1700 строк, для каждой строки создает объект, назначает NSUInteger (значение автоинкремента) и NSString (имя объекта, которое будет отображаться в ячейке) и помещает их в массив источника данных. Весь этот процесс занимает всего около 200-300 миллисекунд - вам придется проверить, не слишком ли много времени для 10 000 записей, но для нескольких тысяч записей было бы хорошо просто прочитать все это. Я помню, что потребление памяти также довольно низкое, не могу посмотреть, сколько именно банкомата.

Затем, когда пользователь нажимает на строку, я запрашиваю массив источника данных, чтобы найти объект, который он только что нажал, и этот объект затем загружает все свои другие значения из базы данных, что он может сделать, так как он знает свой собственный ключ базы данных / id (сам "гидратирует")

Для полноты (используя FMDB ):

NSResultSet *res = [db executeQuery:@"SELECT my_key, my_name FROM table"];
while ([res next]) {
    NSDictionary *dict = [res resultDict];
    MyObj *obj = [MyObj obj];
    obj.id = [dict objectForKey:@"my_key"];
    obj.name = [dict objectForKey:@"my_name"];

    [datasourceArray addObject:obj];
}
2 голосов
/ 29 апреля 2010

Вот то, что я сделал, который работал отлично (я проверил с 3k строк в БД). Приложение EZBudget

  1. Я читаю только индексы в массив, но я делаю это для всей таблицы, сколько бы строк в ней не было
  2. В - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath в do SELECT для indexPath только в качестве индекса
  3. Если необходимо удалить определенные строки (транзакция удалена), я удаляю индекс из массива и удаляю соответствующую строку из таблицы
  4. Когда запись добавляется в таблицу, я получаю, что SQLite возвращает автоинкрементный индекс для вновь добавленной записи. Я беру этот индекс и добавляю в индексный массив

Так что мой индексный массив всегда синхронизирован со всей таблицей. В любой момент я могу ВЫБРАТЬ всю запись по индексу в массиве.

Спасибо всем за предложения!

1 голос
/ 12 октября 2009

Вы всегда можете сделать один оператор select, чтобы получить только «индексы автоинкремента» в том порядке, в котором вы их хотите, и сохранить их в массиве (у вас будет массив с тысячами целых чисел, все должно быть в порядке). Затем в cellForRowAtIndexPath получите правильный «индекс автоинкремента» из вашего массива и извлеките все необходимые данные (я называю «id» вашим «индексом автоинкремента» ниже ...).

NSArray *ids;   // Put the result of 'select id from datatable' here

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Fetch full row where autoincrement index is: [ids objectAtIndex:indexPath.row]

Конечно, вы даже можете использовать int[] (вместо NSArray*), если хотите сэкономить на вызовах на intValue и т. Д. Вы можете выделить int[], используя результат 'select count(*) from datatable

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...