2011-01-09 13 views
8

zostały poszukiwania wysokich i niskich dla tego:Rdzeń danych: przerwać wykonywanie NSFetchRequest

W danych Core, czy istnieje sposób, aby przerwać/stop/anulować i realizacji NSFetchRequest?

Przeprowadzam wyszukiwanie przyrostowe w aplikacji na iPhone'a i próbowałem wszystkich sposobów jej optymalizacji, ale to za mało (mam 42 000 rekordów), więc muszę uruchomić go w NSOperation. Kiedy wpisywany jest nowy znak, muszę anulować poprzednie polecenie fetchRequest, ale [Anulowanie operacji] nic nie robi.

Innym podejściem może być przeniesienie szukanego pola do innego indeksu przerywającego, być może w pamięci, lub może osobnej bazy danych sqlite3, która wydaje się być przerywana przez sqlite_interrupt.

Odpowiedz

2

Moim rozwiązaniem było pozostawienie operacji kwerend dalej uruchomionych, ale aby sprawdzić, czy zostały one anulowane przed wysłaniem zdarzenia, aby zaktualizować interfejs użytkownika.

Nie jest to idealne rozwiązanie, ponieważ wciąż można uruchomić wiele operacji związanych z zapytaniami, których wyników nigdy nie będzie można używać, ale nadal jest trochę szybszy.

2

Krótka odpowiedź - nie, nie bezpośrednio, przepraszam.

Długa odpowiedź - Tak, ale trzeba zrobić sporo pracy lub zrobić to

Trzeba będzie uruchomić go w wątku tła (co brzmi jak jesteś już robić poprzez NSOperation)

Podczas pobierania ustaw limit, aby uzyskać 20 wyników naraz i uruchom go w pętli. Za każdym razem w pętli dodaj wyniki, które dostaje do tablicy. Za każdym razem, gdy pobieranie pobiera każdy zestaw wyników, sprawdź, czy chcesz anulować żądanie.

+2

Ta ostatnia nie działa, ponieważ w przypadku zlecenia sortowanego uzyskanie pierwszego 20 jako pierwszego n zajmuje prawie tyle samo czasu. – mclin

1

Rzeczywiście miałem taki sam problem jak ty. Aby go rozwiązać, używam metody performSelector:afterDelay: To trochę trudne, ale gdy użytkownik szybko wpisuje szybko 3 litery, nie chcę wysyłać 3 próśb, ale tylko jedną, gdy użytkownik zakończy pisanie. Ustawiłem małe opóźnienie o wartości 0,5 lub więcej.

I użyć tego kodu:

[NSObject cancelPreviousPerformRequestsWithTarget:self]; 
[self performSelector:@selector(fetchSearch:) withObject:searchQuery afterDelay:0.5]; 

Jeśli użytkownik wpisze szybko, będzie anulować wcześniejsze wnioski i wysyłać tylko ostatni.

14

Bezpośrednia odpowiedź na twoje pytanie brzmi: nie. Najlepszym wyjściem, z obecnym projektem, jest wykonanie ich w operacji, ale wtedy masz problem z gwintem i spowolnienie. Pamiętaj, że jeśli twoje operacje nie są uruchomione w głównym wątku, potrzebujesz osobnej NSManagedObjectContext dla operacji lub będziesz mieć problemy z wątkami.

Lepsze pytanie: Dlaczego robisz nowe pobranie dla każdej postaci?

Jeśli masz już wyniki pobierania z poprzedniego wyszukiwania i użytkownik nie usunął znaku, po prostu weź istniejące wyniki i uruchom predykat na NSArray. To jeszcze bardziej zawęzi wyszukiwanie, zamiast iść na dysk za każdym razem. Ponieważ jest w pamięci, będzie niezwykle szybki.

rozważyć następujące opcje podczas wdrażania pole wyszukiwania:

  • Hit tylko dysk na pierwszym znaku
  • Hit dysku tylko wtedy, gdy postać zostanie usunięta z pola wyszukiwania
  • Rozważmy docisku objectID i właściwość searchable, aby uniknąć trafień na dysku.

W zależności od tego, czego szukasz (i są sposoby na renormalizację magazynu danych podstawowych w celu usprawnienia wyszukiwania), możesz wstępnie załadować trochę pamięci. Nawet przy rekordach 42K, jeśli właściwości wyszukiwania są wystarczająco małe, możesz je załadować do pamięci.

Prawdopodobnie należy przetestować tę przypadek użycia, jeśli użytkownik zaczyna od naciśnięcia "A".

Która część NSFetchRequest jest wolna? Uderzanie w bazę danych SQLite lub ładowanie danych do pamięci? Na podstawie Twojej odpowiedzi możesz bezpośrednio poprawić skuteczność wyszukiwania.

+0

Świetne, dziękuję! – JOM

+0

Powinieneś również "uderzyć w dysk", jeśli w wyszukiwanym tekście wstawiono dowolny znak. Na przykład użytkownik może wpisać "fooar", a następnie poprawić go, wstawiając brakujący znak, a następne wyszukiwanie będzie "foobar". – Sean

Powiązane problemy