How to use binary flags in Core Data?

前端 未结 4 1827
隐瞒了意图╮
隐瞒了意图╮ 2020-12-24 14:35

I have an int32 attribute in a Core Data database. I use this int as an enum bit field.

Is it possible to create a NSPre

相关标签:
4条回答
  • 2020-12-24 14:35

    Here is one example / application of this technique.

    Say you have a NSManagedObject that has an integer attribute with the keypath "typeValue".

    Somewhere in your code define a bitwise enumeration:

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

    Now to query for managed objects that are of type say One or Three but not Two, do the following:

    SomeType valueOneOrThree = SomeTypeValueOne | SomeTypeValueThree;
    
    NSPredicate *someTypePredicate = [NSPredicate predicateWithFormat:@"(typeValue & %i) == typeValue", valueOneOrThree];
    
    // construct NSFetchRequest as normal with predicate...
    
    0 讨论(0)
  • 2020-12-24 15:01

    NSPredicate can handle it, but I'm not sure if CoreData will accept it as a valid predicate for execution on a data store. It might have trouble converting the bitwise operator into a SQL query (if you're using a SQLite backing store). You'll just have to try it.

    The syntax, however, is just what you'd expect:

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

    Logs:

    3 & 1 > 0
    1
    

    As for doing this on a binary-typed attribute (ie, one defined as data, right?) This probably won't work. Bitwise operators only really make sense when operating on integers (insofar as I understand them), so executing it on an NSData wouldn't make much sense. Convert it to a number first, and then it might work.

    edit

    It would appear that SQLite supports this syntax, since bitwise operators have been around since 2001, which means that Core Data will probably accept it as well.

    0 讨论(0)
  • 2020-12-24 15:01

    rockfakie is so nearly right but

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

    Is what I needed.

    0 讨论(0)
  • 2020-12-24 15:01

    I hardly doubt it.

    But you may use an enum for the values stored in the attribute, and use a direct comparison instead of a bit masking.

    0 讨论(0)
提交回复
热议问题