问题
In my core data model, I have an entity with an optional NSNumber attribute.
How do I test to see if the value in that attribute is valid or not?
When I test for nil... doesn't work.
[self numberAttribute] == nil // always returns NO
When I test for a zero value int, that doesn't work.
[[self numberAttribute] intValue] == 0 // always returns no
As a matter of fact, [[self numberAttribute] intValue]] returns something that looks suspiciously like a pointer to a memory address.
Anyone have any idea what I am doing wrong?
EDIT: OK, the bug was in a totally unrelated part of the code. NSNumber and Core Data are functioning exactly as one would expect. That said, I am going to go with the suggested approach of making the attribute non-optional and specifying 0 as the default value.
Just putting this note here for a little while for anyone who was watching this question, then I am deleting it.
回答1:
According to the documentation,
You can specify that an attribute is optional—that is, it is not required to have a value. In general, however, you are discouraged from doing so—especially for numeric values (typically you can get better results using a mandatory attribute with a default value—in the model—of 0). The reason for this is that SQL has special comparison behavior for NULL that is unlike Objective-C's nil. NULL in a database is not the same as 0, and searches for 0 will not match columns with NULL.
false == (NULL == 0)
false == (NULL != 0)
Moreover, NULL in a database is not equivalent to an empty string or empty data blob, either:
false == (NULL == @"")
false == (NULL != @"")
So, try a test with NULL, which is not nil. Better yet, set a default and change the attribute to be non-optional. That's what I've ended up doing in my models, and in practice it works quite well.
Edit: See my comment above. I tried creating a new managed object with an optional attribute not set, and it was nil.
BOOL isNil = ([newManagedObject numberAttribute] == nil); //equals YES
Another edit: I came back to this later and checked out an object loaded from the cache in the debugger (gdb is your friend!). It was trying to access memory location 0x0, which is NULL.
回答2:
If you are getting a large value back that looks like a pointer, perhaps it is NaN (not a number)?
If so, you could check with:
isnan([[self numberAttribute] doubleValue])
Or, possibly it is some other constant along the lines of NSNotFound (though probably more Core Data specific).
回答3:
If it looks like a pointer, it may be a pointer to NSNumber instance. Make sure you don't have mismatch between core data model and the class (e.g. NSInteger where NSNumber* is expected).
If you have scalar in your class, then you need to note that yourself in setNilValueForKey:.
来源:https://stackoverflow.com/questions/1188413/storing-optional-nsnumber-in-core-data