Realm Cocoa: Finden mehrerer Objekte von PKs

Lange Zeit Lauerer, erstes Mal Fragesteller.

Ich verwende Realm Cocoa (von Realm.io) in einem Projekt und habe Probleme, die Suche nach PKs durchzuführen. Nehmen wir an, ich habe eine Entität namensRLMFoo mit einem Primärschlüssel namensbar. Ich habe auch eine Liste von PKs, die beispielsweise in einem Array gespeichert sind:

NSArray *primaryKeys = @[@"bar1", @"bar2", @"bar3"]

Gibt es eine Möglichkeit, alle Entitäten der Klasse @ abzurufeRLMFoo aus meinem Bereich in einer einzigen Abfrage?

Ich habe es bisher versucht:

Predicate with format:[RLMFoo objectsInRealm:realm withPredicate:[NSPredicate predicateWithFormat:@"bar IN %@", primaryKeys]]; Realms wo:[RLMFoo objectsInRealm:realm where:@"bar IN %@", strippedIds];Predicate with block:

.

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id
evaluatedObject, NSDictionary *bindings) {
                    RLMFoo *foo = (RLMFoo *)evaluatedObject;
                    return [primaryKeys containsObject:foo.bar];
                }];
        [RLMFoo objectsInRealm:realm withPredicate:predicate];

Aber das einzige, was ich bisher als funktionierend empfunden habe, ist das Abfragen des Realms nach jedem Primärschlüsselwert und das Aggregieren der Ergebnisse, was langsam erscheint:

NSMutableArray *results = [NSMutableArray new];
for (NSString *primaryKey in primaryKeys) {
    RLMFoo *obj = [RLMFoo objectInRealm:realm forPrimaryKey:primaryKey];
    if (obj) {
        [results addObject:obj];
    }
}

Weiß jemand einen besseren Weg, um es zu tun?

========= Erklären, warum die ersten drei Methoden nicht funktionieren =======

1) Der Grund, warum dies nicht funktioniert, geht aus der Ausnahmemeldung hervor: IN nimmt nur 2 Werte an, obwohl die SQL-Version von IN so viele wie nötig annehmen sollte. Wie wir aus dem Quellcode von @ sehen könnRLMQueryUtil.mm, das gleiche gilt für den BETWEEN-Operator:

        if (compp.predicateOperatorType == NSBetweenPredicateOperatorType || compp.predicateOperatorType == NSInPredicateOperatorType) {
        // Inserting an array via %@ gives NSConstantValueExpressionType, but
        // including it directly gives NSAggregateExpressionType
        if (exp1Type != NSKeyPathExpressionType || (exp2Type != NSAggregateExpressionType && exp2Type != NSConstantValueExpressionType)) {
            @throw RLMPredicateException(@"Invalid predicate",
                                         @"Predicate with %s operator must compare a KeyPath with an aggregate with two values",
                                         compp.predicateOperatorType == NSBetweenPredicateOperatorType ? "BETWEEN" : "IN");
        }

Hier ist der Stack-Trace:

*** Terminating app due to uncaught exception 'Invalid predicate', reason: 'Predicate with IN operator must compare a KeyPath with an aggregate with two values'
*** First throw call stack:
(
    0   CoreFoundation      0x03334946 __exceptionPreprocess + 182
    1   libobjc.A.dylib     0x0292aa97 objc_exception_throw + 44
    2   <redacted>          0x00190569 _ZN12_GLOBAL__N_127update_query_with_predicateEP11NSPredicateP9RLMSchemaP15RLMObjectSchemaRN7tightdb5QueryE + 2553
    3   <redacted>          0x0018f7ea _Z27RLMUpdateQueryWithPredicatePN7tightdb5QueryEP11NSPredicateP9RLMSchemaP15RLMObjectSchema + 378
    4   <redacted>          0x0018b23c _Z13RLMGetObjectsP8RLMRealmP8NSStringP11NSPredicate + 748
    5   <redacted>          0x0017d721 +[RLMObject objectsInRealm:withPredicate:] + 161

2) Dies ist in Grund und Stack-Trace sehr ähnlich:

*** Terminating app due to uncaught exception 'Invalid predicate', reason: 'Predicate with IN operator must compare a KeyPath with an aggregate with two values'
*** First throw call stack:
(
    0   CoreFoundation      0x03328946 __exceptionPreprocess + 182
    1   libobjc.A.dylib     0x0291ea97 objc_exception_throw + 44
    2   <redacted>          0x00184599 _ZN12_GLOBAL__N_127update_query_with_predicateEP11NSPredicateP9RLMSchemaP15RLMObjectSchemaRN7tightdb5QueryE + 2553
    3   <redacted>          0x0018381a _Z27RLMUpdateQueryWithPredicatePN7tightdb5QueryEP11NSPredicateP9RLMSchemaP15RLMObjectSchema + 378
    4   <redacted>          0x0017f26c _Z13RLMGetObjectsP8RLMRealmP8NSStringP11NSPredicate + 748
    5   <redacted>          0x00171751 +[RLMObject objectsInRealm:withPredicate:] + 161
    6   <redacted>          0x00171465 +[RLMObject objectsInRealm:where:args:] + 213
    7   <redacted>          0x001712f3 +[RLMObject objectsInRealm:where:] + 419

3) Auch dieser ist sehr ähnlich. Es läuft darauf hinaus, dass der Realm-Support für den vollständigen Funktionsumfang von NSPredicate nicht ausreicht.

*** Terminating app due to uncaught exception 'Invalid predicate', reason: 'Only support compound and comparison predicates'
*** First throw call stack:
(
    0   CoreFoundation      0x03308946 __exceptionPreprocess + 182
    1   libobjc.A.dylib     0x028fea97 objc_exception_throw + 44
    2   <redacted>          0x001638bd _ZN12_GLOBAL__N_127update_query_with_predicateEP11NSPredicateP9RLMSchemaP15RLMObjectSchemaRN7tightdb5QueryE + 4397
    3   <redacted>          0x0016240a _Z27RLMUpdateQueryWithPredicatePN7tightdb5QueryEP11NSPredicateP9RLMSchemaP15RLMObjectSchema + 378
    4   <redacted>          0x0015de5c _Z13RLMGetObjectsP8RLMRealmP8NSStringP11NSPredicate + 748
    5   <redacted>          0x00150341 +[RLMObject objectsInRealm:withPredicate:] + 161

Antworten auf die Frage(4)

Ihre Antwort auf die Frage