iPhone: Save boolean into Core Data

后端 未结 4 1879
情话喂你
情话喂你 2021-01-30 00:47

I have set up one of my core data attributes as a Boolean. Now, I need to set it, but XCode keeps telling me that it may not respond to setUseGPS.

[ride setUseG         


        
相关标签:
4条回答
  • 2021-01-30 01:19

    The "fix" for this (IMHO, it's a bug in Apple's SDK) is to add the following code to your CoreData-generated class. NB: if you do this in a category, in a separate file, then you don't have to re-copy/paste it each time you regenerate the CoreData classes inside Xcode

    - (BOOL)useGPS
    {
        [self willAccessValueForKey:@"useGPS"];
        BOOL myuseGPS = [[self primitiveUseGPS] boolValue];
        [self didAccessValueForKey:@"useGPS"];
        return myuseGPS;
    }
    
    - (void)setUseGPS:(BOOL)newValue
    {
        [self willChangeValueForKey:@"useGPS"];
        [self setPrimitiveUseGPS:[NSNumber numberWithBool:newValue]];
        [self didChangeValueForKey:@"useGPS"];
    }
    
    0 讨论(0)
  • 2021-01-30 01:25

    As an alternative approach to the accepted answer, you can simply change the typing from an NSNumber* to a BOOL in the managed object interface definition, such as:

    @property (nonatomic) BOOL useGPS;   // Notice that the 'retain' is also removed as we're now dealing with a scalar rather than an NSObject
    

    Various alternative approaches are discussed here, but Chris Hanson's response was most illuminating for me, especially:

    If you have a numeric attribute (including a boolean attribute) that's required, you can just type it as a scalar instead, and Core Data will do the right thing:

    @property (nonatomic) BOOL isDone;

    Even if the attribute is optional, that'll still work - it'll just conflate "not present" with "false."

    and for a more aligned Cocoa implementation:

    One other thing you might want to do is name the property "done" and just specify the getter as "isDone." That's the usual Cocoa naming convention:

    @property (nonatomic, getter=isDone) BOOL done;

    Then you can write "if (item.done) { ... }" or "item.done = NO;" and the compiler will still generate -isDone for accesses of the property.

    Thanks Chris, and hope that this helps someone.

    0 讨论(0)
  • 2021-01-30 01:27

    Core Data "does not have" a Boolean type (it does, but it is an NSNumber).

    So to set the equivalent of useGPS = YES.

    [entity setUseGPS:[NSNumber numberWithBool:YES]];
    

    And the other way around:

    BOOL isGPSOn = [[entity useGPS] boolValue];
    

    Update: As pointed out by SKG, With literals in Objetive-C you can now do it in a simpler way:

    [entity setUseGPS:@YES];
    
    BOOL isGPSOn = entity.useGPS.boolValue;
    
    0 讨论(0)
  • 2021-01-30 01:45

    Just to complement @RickiG answer, the way to create a NSNumber from a Booland vice-versa in Swift (at least since v4.2) is:

    let nsNumberFromBool = NSNumber(booleanLiteral: true) // or false
    let boolFromNSNumber = nsNumberFromBool.boolValue
    
    0 讨论(0)
提交回复
热议问题