我有一个具有如下属性的模型:
当我设置它的值时,例如:
model.isResolved = @YES;
保存在模型中的 NSNumber “忘记”它是一个布尔值:
NSLog(@"%@", strcmp([self.isResolved objCType], @encode(BOOL)) == 0 ? @"equal" : @"different");
打印“不同”。那是怎么回事?
我有一个具有如下属性的模型:
当我设置它的值时,例如:
model.isResolved = @YES;
保存在模型中的 NSNumber “忘记”它是一个布尔值:
NSLog(@"%@", strcmp([self.isResolved objCType], @encode(BOOL)) == 0 ? @"equal" : @"different");
打印“不同”。那是怎么回事?
Core Data 为托管对象类的所有属性(和关系)动态生成 getter 和 setter 方法。这些访问器方法不同于由实例变量支持的“常规”@synthesized 访问器方法。
特别是,如果您设置一个属性,然后再次检索该属性值,您可以获得一个与“原始”对象不同的对象。以下测试显示了这一点,foo1
它是具有布尔属性“show”的核心数据实体的实例:
NSNumber *yes = @YES;
NSLog(@"yes = %p, type = %s", yes, [yes objCType]);
foo1.show = yes;
NSNumber *val = foo1.show;
NSLog(@"val = %p, type = %s", val, [val objCType]);
输出:
yes = 0x16e595c, type = c
val = 0x744c150, type = i
因此,即使您将属性设置为c = char编码数字,getter 方法也会返回i = int编码数字。
此测试是在 iOS 模拟器中完成的。有趣的是,在 OS X 64 位上运行的相同测试返回一个c = char编码的数字。
因此,Core Data 对象中布尔和其他标量属性的实际编码可能应该被视为 Core Data 的实现细节。
如果您需要检查模型中定义的核心数据类型,您可以使用对象实体描述而不是objCType
:
NSEntityDescription *entity = [foo1 entity];
NSAttributeDescription *attr = [[entity attributesByName] objectForKey:@"show"];
NSAttributeType type = [attr attributeType];
if (type == NSBooleanAttributeType) {
NSLog(@"Its a Boolean!");
}
它存储为 NSNumber - 顺便说一下,@YES 正在创建一个类似 NSNumber
[NSNumber numberWithBool:YES]
所以要让布尔值回来,你可以这样做:
[isResolved boolValue]
(您可以通过在创建模型时勾选使用标量属性来避免这种情况)