2011-01-17 14 views
20

Ich habe ein int32 Attribut in einer Core Data-Datenbank. Ich benutze diese int als enum Bit-Feld.Wie werden binäre Flags in Core Data verwendet?

Ist es möglich, einen NSPredicate zu erstellen, um Elemente basierend auf dem binären Wert dieses int abzufragen? Etwas wie @"bitFieldAttribute & 0x0001"?

Ich frage mich auch, ob dies mit einem binären typisierten Attribut möglich ist?

Antwort

25

NSPredicate kann ich damit umgehen, aber ich bin mir nicht sicher, ob CoreData es als gültiges Prädikat für die Ausführung in einem Datenspeicher akzeptiert. Es könnte Probleme beim Konvertieren des bitweisen Operators in eine SQL-Abfrage geben (wenn Sie einen SQLite-Sicherungsspeicher verwenden). Du musst es nur versuchen.

Die Syntax ist jedoch genau das, was man erwarten würde:

NSPredicate * p = [NSPredicate predicateWithFormat:@"(3 & 1) > 0"]; 
NSLog(@"%@", p); 
NSLog(@"%d", [p evaluateWithObject:nil]); 

Logs:

3 & 1 > 0 
1 

Da diese auf einem binären typisierte Attribut zu tun (dh, eine als data definiert , oder?) Das wird wahrscheinlich nicht funktionieren. Bitweise Operatoren sind nur sinnvoll, wenn sie mit ganzen Zahlen arbeiten (soweit ich sie verstehe), daher wäre es nicht sinnvoll, sie auf einer NSData auszuführen. Konvertiere es zuerst in eine Zahl und dann könnte es funktionieren.

bearbeiten

Es scheint, dass SQLite diese Syntax unterstützt, da bitwise operators have been around since 2001, was bedeutet, dass Core Data wird es auch wahrscheinlich akzeptieren.

+0

Das funktioniert !!!! Danke vielmals ! Ich war auch sehr zweifelhaft, dass CodeData in SQL übersetzen würde, aber ich habe es gerade getestet und es scheint zu funktionieren. – CodeFlakes

+0

Fast immer sicherer zu überprüfen '(x & Bits)! = 0' statt' (x & Bits)> 0'. Der Grund dafür ist, dass das Setzen des höchsten Bits die Zahl negativ machen kann. Einzige Ausnahme ist, wenn Sie sich völlig sicher sind, dass die Nummer nicht signiert ist. – HughHughTeotl

-1

Ich bezweifle es kaum.

Sie können jedoch einen enum für die im Attribut gespeicherten Werte verwenden und einen direkten Vergleich anstelle einer Bitmaskierung verwenden.

+0

Ich verstehe nicht, was Sie meinen. Ich möchte Entitäten holen, die bestimmten Bitwerten entsprechen (nicht auf die exakt gleiche Bitsequenz beschränkt). – CodeFlakes

+0

Können Sie ein Beispiel angeben, warum Sie die Bit-Maskierungstechnik benötigen? –

+0

@CiprianL. hier ist es: Ich habe eine Reihe von Entitäten, die Kreaturen repräsentieren (viele Kreaturen), und ich habe eine Menge Welten (wie 16 oder so), in die ich diese Kreaturen hineinbringen sollte.Die gleichen Kreaturen können in mehreren Welten dargestellt werden. So, jetzt muss ich Kreaturen holen, die in den Welten "A", "B" und "D" präsentiert werden sollen. – igrek

8

Hier ist ein Beispiel/Anwendung dieser Technik.

Angenommen, Sie haben ein NSManagedObject mit einem ganzzahligen Attribut mit dem Schlüsselpfad "typeValue".

Irgendwo im Code definieren eine bitweise Aufzählung:

typedef enum SomeType { 
    SomeTypeValueOne = 0x1, 
    SomeTypeValueTwo = 0x2, 
    SomeTypeValueThree = 0x4 
} SomeType; 

Jetzt für verwaltete Objekte abzufragen, die vom Typ sind sagen, eine oder drei, aber nicht zwei, wie folgt vorgehen:

SomeType valueOneOrThree = SomeTypeValueOne | SomeTypeValueThree; 

NSPredicate *someTypePredicate = [NSPredicate predicateWithFormat:@"(typeValue & %i) == typeValue", valueOneOrThree]; 

// construct NSFetchRequest as normal with predicate... 
7

rockfakie ist so fast richtig, aber

NSPredicate *someTypePredicate = [NSPredicate predicateWithFormat:@"(typeValue & %i) == %i", valueOneOrThree,valueOneOrThree]; 

Ist was ich brauchte.

+0

Hnmm, ich bekomme CoreData Barfing mit dem Fehler "'NSInvalidArgumentException', Grund: 'Nicht unterstützter Funktionsausdruck gesperrt & 8" mit dem Ausdruck '(banned & 8) == 0' – chadbag

+0

Kannst du bitte deine gesamte NSPredicate-Definition posten? –

+0

wurde behoben. War ein blöder Tippfehler des Eigentumsnamens wegen eines Gehirn-Furzes (hatte sich mit der mysql-Seite beschäftigt, die die App benutzt, um ihre Objekte zu füllen und den mysql-Spaltennamen anstelle des CD-Eigenschaftsnamens verwendete). Vielen Dank. – chadbag