2012-11-02 11 views
8

Wpadłem na rozwiązanie tego przy użyciu podzapytania, ale nie rozumiem, dlaczego to, co próbowałem zrobić, nie zadziałało.Podstawowe dane, NSPredicate, DOWOLNY klucz.path == zero

Oto mój model danych. Pobiegam po poradach.

enter image description here

mogę wykonać następujące czynności jako orzecznik:

[NSPredicate predicateWithFormat:@"ANY conditions.terrain == %@", aTerrainObject]; 

że działa prawidłowo i zwraca każdą radę, gdzie co najmniej jeden z warunków jej ma ten typ terenu.

Jednak gdy próbuję to zrobić, to nie:

[NSPredicate predicateWithFormat:@"ANY conditions.terrain == nil"]; 

Co chcę zrobić, to wrócić jakąkolwiek radę, gdzie co najmniej jeden z warunków jej nie posiada zestaw rodzaju terenu.

Jednak dodaje działa:

[NSPredicate predicateWithFormat:@"SUBQUERY(conditions, $x, $x.terrain == nil)[email protected] > 0"]; 

Może ktoś wyjaśnić, dlaczego, kiedy szukając zera, nie mogę użyć składni ANY?

+0

Dobra uwaga tutaj. + 1 –

Odpowiedz

24

Czy ktoś może wyjaśnić, dlaczego, szukając zer, nie mogę użyć DOWOLNEJ składni?

Tak! Oto, co się dzieje.

[NSPredicate predicateWithFormat:@"ANY conditions.terrain == nil"]; 

Najpierw podzielenie się do odpowiednich wyrażeń lewej i prawej:

conditions.terrain 

ta zostanie oceniona przez poświęcenie obiektu SELF (instancję Advice) i wzywając valueForKeyPath:@"conditions.terrain". Rezultatem tego keypath będzie kolekcja. Jesteś w zasadzie robi:

Advice *a = ...; 
NSSet *conditions = [a conditions]; 
NSSet *terrains = [conditions valueForKey:@"terrain"]; 

Tak, masz zbiór (potencjalnych) Terrain przypadkach. Co wiemy o kolekcjach w Objective-C? Po pierwsze, nie mogą zawierać nil. Mogą zawierać tylko obiekty.Oznacza to, że podczas wykonywania części predykatu ANY nastąpi iteracja elementów w tablicy i zobaczenie, że żaden z nich nie jest nil.

Tak więc Twój predykat się nie udaje. Próbowałem grać z innymi wersjami (używając [NSNull null] zamiast nil itd.), Ale żaden z nich nie działał.

Wygląda więc na to, że korzystanie z rozwiązania SUBQUERY jest tak dobre, jak to tylko możliwe. Gorąco polecam filing a bug wyszczególniając twoje oczekiwania i wyrażając, dlaczego uważasz, że to powinno działać.

+1

+1 za głębokie wyjaśnienie. –

+0

Doskonała odpowiedź. Dziękuję za dokładność i precyzję. –

0

Uważam, że nie można użyć nil w zapytaniu. Powinieneś użyć NULL lub konstruktu ciągu formatów, takiego jak "ANY conditions.terrain == %@", nil.

Co mnie zastanawia to, że podzapytanie działa ...

powyższych nie jest prawidłowa, jak NULL i NIL mogą być stosowane zamiennie.

Zamiast tego, NSExpression Class Reference podaje dokładnie swój wzór (z @count) jako preferowany przykład.

Czy sprawdziłeś, czy relacja terenu jest opcjonalna?

+0

Tak, to opcjonalne. –

Powiązane problemy