2011-01-17 15 views
20

Tengo un atributo int32 en una base de datos Core Data. Uso este int como un campo de enum bit.¿Cómo usar banderas binarias en Core Data?

¿Es posible crear un NSPredicate para consultar elementos basados ​​en el valor binario de este int? Algo así como @"bitFieldAttribute & 0x0001"?

¿Me pregunto si esto es posible con un atributo de tipo binario?

Respuesta

25

NSPredicate puede manejarlo, pero no estoy seguro si CoreData lo aceptará como un predicado válido para la ejecución en un almacén de datos. Puede tener problemas para convertir el operador bit a bit en una consulta SQL (si está utilizando una tienda de respaldo SQLite). Tendrás que probarlo.

La sintaxis, sin embargo, es justo lo que se espera:

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

Registros:

3 & 1 > 0 
1 

En cuanto a hacer esto en un atributo binario escrito (es decir, uno define como data , ¿verdad?) Esto probablemente no funcionará. Los operadores bit a bit solo tienen sentido cuando se trabaja con enteros (en la medida en que los entiendo), por lo que ejecutarlo en un NSData no tendría mucho sentido. Primero conviértalo en un número, y luego podría funcionar.

edición

Parecería que SQLite es compatible con esta sintaxis, ya que bitwise operators have been around since 2001, lo que significa que Core Data probablemente lo aceptará también.

+0

que funciona !!!! Muchas gracias ! También estaba muy dudoso de que CodeData se tradujera a SQL, pero acabo de probarlo y parece funcionar. – CodeFlakes

+0

Casi siempre es más seguro para comprobar '(X & bits)! = 0' en lugar de' (X & bits)> 0'. La razón es que establecer el bit más alto puede convertir el número en negativo. La única excepción es cuando está completamente seguro de que el número no está firmado. – HughHughTeotl

-1

No lo dudo.

Pero puede usar enum para los valores almacenados en el atributo y usar una comparación directa en lugar de un enmascaramiento de bits.

+0

No entiendo lo que quieres decir. Lo que quiero hacer es buscar entidades que coincidan con ciertos valores de bit (no se limita a la misma secuencia de bits). – CodeFlakes

+0

¿Puedes dar un ejemplo de por qué necesitas la técnica de enmascaramiento de bits? –

+0

@CiprianL. aquí está: tengo un grupo de entidades, que representan criaturas (muchas criaturas), y tengo un montón de mundos (como 16 más o menos), donde debería presentar esas criaturas.Las mismas criaturas se pueden presentar en múltiples mundos. Así que ahora, tengo que ir a buscar a las criaturas que deben presentarse en mundos 'A', 'B' y' D' – igrek

8

Aquí hay un ejemplo/aplicación de esta técnica.

Supongamos que tiene un objeto NSManagedObject que tiene un atributo entero con la ruta de clave "typeValue".

En algún lugar de su código define una enumeración bit a bit:

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

ahora para consultar objetos gestionados que son de tipo Diga uno o tres, pero no dos, hacer lo siguiente:

SomeType valueOneOrThree = SomeTypeValueOne | SomeTypeValueThree; 

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

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

rockfakie es casi correcto, pero

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

Es lo que necesitaba.

+0

Hnmm, estoy consiguiendo CoreData barfing con el error " 'NSInvalidArgumentException', razón: 'expresión de función no compatible prohibido y 8" con la expresión' (prohibido y 8) == 0' – chadbag

+0

Se puede publicar su definición completamente NSPredicate, por favor? –

+0

ha sido reparado. Fue un error estúpido del nombre de la propiedad debido a un pedo cerebral (había sido tratar con el lado mysql que la aplicación utiliza para poblar sus objetos y utiliza el nombre de columna MySQL en lugar del nombre de la propiedad de CD). Gracias. – chadbag