Vincent Sit
Vincent Sit

Reputation: 2352

Core Data 64 bit transition

In the 32-bit systems run correctly, when running in 64-bit system environment (5s), the following warning appears.

CoreData: warning: Property 'type' is a 64 bit scalar type on class 'EOTProduct' that does not match its entity's property's 32 bit scalar type.  Implicit coercion to 32 bits in the database is not recommended.
CoreData: warning: Property 'setType:' is a 64 bit scalar type on class 'EOTProduct' that does not match its entity's property's 32 bit scalar type.  Implicit coercion to 32 bits in the database is not recommended.
......

I think the type of Core Data attribute can not dynamically changed, then I should choose Integer 32 or Integer 64? If I choose Integer 32, then it should not be adapted to a 64-bit environment. If I choose Integer 64, then the 32-bit systems will waste a lot of memory? I have not thought of a good solution, if someone has already solved this problem, Can you share how you solve it? Thank you!

Upvotes: 1

Views: 912

Answers (1)

Olaf
Olaf

Reputation: 3042

If you are in the position to migrate the data model from NSInteger to NSNumber you should go that route.

Otherwise, if you are stuck with an integer, define it like:

@interface  EOTProduct
@property (nonatomic) int32_t type;
@end

@interface EOTProduct (PrimitiveAccessors)
- (NSNumber *)primitiveType;
- (void)setPrimitiveType:(NSNumber*)value;
@end

// -----

@implementation  EOTProduct
// thereis no >@dynamic type< here
-(int32_t)type {
    [self willAccessValueForKey:@"type"];
    NSNumber *tmpValue = [self primitiveType];
    [self didAccessValueForKey:@"type"];
    return (tmpValue != nil) ? [tmpValue intValue] : 0.0; // Or a suitable representation for nil.
}

-(void)setType:(int32_t)value {
    [self willChangeValueForKey:@"type"];
    [self setPrimitiveType:[NSNumber numberWithInt:value]];
    [self didChangeValueForKey:@"type"];
}
@end

In your code when accessing the attribute remember to treat it as int32_t not as NSInteger. As you have found an NSInteger will be a 64bit on a iPhone 5s and a 32bit on the older devices. Treating it as int32_t will avoid strange overflow errors and such.

I did chose above solution because migrating was causing more headaches. And here was no noticeable impact on memory consumption wrt. to the ints.

Upvotes: 1

Related Questions