, если вы сделаете конструктор асинхронным, после создания объекта вы можете столкнуться с такими проблемами, как пустые значения, а не объекты экземпляра. Например:
MyClass instance = new MyClass();
instance.Foo(); // null exception here
Вот почему они этого не позволяют.
Вы уверены, что любой из ваших вызовов SQLite успешен? Вы должны инициализировать результат
значением nil
, чтобы ваша функция возвращала nil
, если обнаружены какие-либо ошибки.
Три (возможно, связанные) проблемы с вашим кодом:
Индекс sqlite3_column_text
должен начинаться с нуля; вы передаете 2
, что должно относиться к третьему столбцу. Вы, вероятно, хотите сдать 1
. Из документы :
... второй аргумент - это индекс столбца, для которого должна быть возвращена информация. Крайний левый столбец набора результатов имеет индекс 0.
Вам действительно не следует использовать SELECT *
.Укажите нужные столбцы!
Вы должны специализировать свой запрос на связывании значений, а не на конкатенации строк! Ваш код изобилует возможностью SQL-инъекций (не говоря уже о некорректных запросах).
Например (без проверки ошибок):
const char *query = "SELECT * FROM ? WHERE ?=?";
sqlite3_stmt *compiledQuery;
sqlite3_prepare_v2(database, query, -1, &compiledQuery, NULL);
sqlite3_bind_text(compiledQuery, 1, "Lessons", -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledQuery, 2, "Chrono", -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledQuery, 3, "0001", -1, SQLITE_TRANSIENT);
Обратите внимание, что индекс здесь основан на 1 (я не знаю, почему они это делают). Из документации :
Второй аргумент - это индекс устанавливаемого параметра SQL. Крайний левый параметр SQL имеет индекс 1.