2013-05-26 6 views
5

Prowadzę serię zapytań w całym cyklu życia mojej aplikacji.Kiedy otworzyć i zamknąć SQlite DB w cyklu życia systemu iOS?

Obecnie używam FMDB (wrapper Objective-C wokół interfejsu API Sqlite C), a ja otwieram i zamykam przed każdym zapytaniem.

FMDatabase * db = [FMDatabase databaseWithPath:pathToMyDB]; 
[db open] 
FMResultSet * s = [db executeQuery:@"SELECT * FROM myTable"]; 
// Use FMResultSet 
[db close]; 

Otwórz i zamknij spust fopen() i fclose() niżej, więc wierzę mogę zdobyć siłą rzeczy wygraną poprzez utrzymywanie bazy otwarte.

Uważam jednak, że tymczasowe obiekty będą się budować, co może prowadzić do problemów z pamięcią. Closing the database usuwa obiekty tymczasowe.

  • Kiedy należy otworzyć i zamknąć połączenie z bazą danych? (np. aplikacja wprowadziła backgound?)
  • Czy powinienem uruchomić VACUUM w sytuacjach z małą ilością pamięci?

Odpowiedz

1

Baza danych nie tworzy i/lub nie zatrzymuje żadnych obiektów (a przynajmniej nie powinno). API C to po prostu przydatny sposób na użycie zapytań SQL, ale po ich wykonaniu powinny zostać wydane.

Teraz dla zwracanych obiektów zapytania są one po prostu kopiowane do pliku FMResultSet. Kiedy zwolnisz, że ich nie ma.

Imo, jeśli sama baza danych nie jest zbyt duża, powinieneś zachować odniesienie do niej w swojej aplikacji delegata (gwarancja, że ​​żyjesz przez całe życie aplikacji). Po wejściu do aplikacji/wznowieniu z tła otwórz bazę danych i po przejściu do tła/zamknięcia po prostu zamknij ją.

Należy pamiętać, że AppDelegate jest singletonem (myślę) i można uzyskać dostęp do bazy danych za pomocą numeru (AppDelegate*)[[UIApplication sharedApplication]delegate].your_db z dowolnego miejsca w aplikacji, aby wykonać rzeczywiste zapytania.

Używanie VACUUM spowoduje awarię aplikacji, jeśli spróbujesz ją wywołać, gdy otrzymasz ostrzeżenie o zapamiętywaniu. Pomyśl o tym: aby zmienić kolejność bazy danych, należy ją załadować do pamięci (lub przynajmniej jej części), jeśli masz już ostrzeżenie o pamięci ... poof ... crash.

Można przetestować, czy baza danych utrzymuje obiekty w pamięci. Po prostu wykonaj 100 zapytań w odstępie 1 sekundy (lub naciśnij przycisk) i obserwuj w instrumentach gdzie i czy pamięć rośnie. Możesz mieć wyciek w swojej aplikacji (lub w samym opakowaniu) i obwiniasz go w bazie danych.

+0

Dziękuję za odpowiedź. Czy jesteś w 100% pewien, że baza danych nie tworzy i/lub nie zatrzymuje żadnych obiektów? Prawdopodobnie masz rację, ale ta dokumentacja mówi: "zwróć SQLITE_OK, jeśli obiekt sqlite3 zostanie pomyślnie zniszczony ** i wszystkie powiązane zasoby zostaną zwolnione **" http://www.sqlite.org/c3ref/close.html – Robert

+0

Myślę, że powiązane zasoby odnoszą się do samego połączenia i kilku innych rzeczy, które są potrzebne, aby uzyskać do niego dostęp. Jak już powiedziałem, nie jestem pewien, czy serwerowe bazy danych to robią. Z drugiej strony nie trzeba ich otwierać, per se. Zrób tak jak powiedziałem, przetestuj go w następujący sposób: w oddzielnej otwartej bazie danych klasy, wykonuj absurdalną ilość zapytań (podczas oglądania pamięci), a następnie zamknij ją. Powinno być oczywiste, co się dzieje. Jeśli zachowa jakiś obiekt, zobaczysz, że pamięć rośnie, aż do awarii aplikacji, jeśli nie wszystko powinno pozostać przy względnie stałym przydzielaniu pamięci. To najprostszy sposób, aby się upewnić. – skytz

Powiązane problemy