use*_*255 2 iphone core-data ios4 ios5
这是我第一次尝试使用ARC和Core Data.我似乎无法弄清楚为什么我的代码崩溃了.
在.h我有:
@interface Foo : NSObject {
}
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSString *email;
@property (nonatomic) BOOL myBool;
@property (nonatomic) float myFloat;
Run Code Online (Sandbox Code Playgroud)
在他们中
@implementation User
@dynamic name;
@dynamic email;
@dynamic myBool;
@dynamic myFloat;
Run Code Online (Sandbox Code Playgroud)
User *user = (User *)[NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:[appDelegate managedObjectContext]];
[user setName:[[[dictionary objectForKey:@"user"] objectForKey:@"user"]objectForKey:@"name"]];
[user setEmail:[[[dictionary objectForKey:@"user"] objectForKey:@"user"]objectForKey:@"email"]];
[user setAuthorisation_token:[[[dictionary objectForKey:@"user"] objectForKey:@"user"]objectForKey:@"authentication_token"]];
[user setMyFloat:5]; <------ crash when set to anything other than 0 (eg,setting to FALSE will crash it).
[user setMyBool:FALSE]; <---- crash when set this to anything other than 0.
Run Code Online (Sandbox Code Playgroud)
基本上每当我尝试使用字符串以外的类型时,我会在该特定行上获得EXEC崩溃.当我使用字符串时,一切都很好.在my.xcdatamodeld文件中,我将myFloat设置为FLOAT,将myBool设置为BOOLEAN
kill
error while killing target (killing anyway): warning: error on line 2184 of "/SourceCache/gdb/gdb-1708/src/gdb/macosx/macosx-nat-inferior.c" in function "void macosx_kill_inferior_safe()": (os/kern) failure (0x5x)
quit
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)
您不能将@dynamic用于基元(如float和BOOL),因为Core Data不会为它们创建实现.
因此,您的代码崩溃的原因是因为当您使用时,@dynamic您告诉编译器"我保证这些getter和setter的实现将在运行时可用".但由于Core Data不会创建它们,因此您的代码会尝试调用不存在的方法.
相反,你可以做两件事:对BOOL和浮点数使用NSNumber或者实现你自己的getter和setter.
使用NSNumber:
Core Data仅使用对象而不是基元,但您可以在Model中指定boolean或float.当你打电话时,[user myFloat]你实际上会得到一个带有浮动值的NSNumber.要访问原语,请调用float f = [[user myFloat] floatValue];.布尔值也是如此,它也存储在NSNumber中.因此,当您尝试访问它时,您将获得一个需要调用BOOL b = [[user isMyBool] boolValue];以获取原语的NSNumber .
反过来说,当设置myFloat和myBool时,你需要将它们存储在NSNumber中,例如[user setMyFloat:[NSNumber numberWithFloat:f]];和[user setMyBool:[NSNumber numberWithBool:b]];.
要使用此方法,您必须将最后两个属性更改为
@property (nonatomic, strong) NSNumber *myBool;
@property (nonatomic, strong) NSNubmer *myFloat;
Run Code Online (Sandbox Code Playgroud)
但你可以保留@dynamic两者.
实现你自己的getter和setter:
为方便起见,你可能希望你的"user"对象直接获取和设置基本类型float和BOOL.在这种情况下,您应该将属性保持为float和bool,并在实现文件(.m)中删除@dynamicmyFloat和myBool 的行.
要实现getter和setter,您需要了解一些关于KVC/KVO和Core Data的知识.简而言之:您需要告诉系统何时访问或更改属性以及何时完成访问或更改属性,因为Core Data不会为您执行此操作.在"将访问/更改"和"确实访问/更改"之间,您可以自由地检索或修改属性.还有一点需要注意的是,Core Data仍然无法直接保存BOOL和float,因此在获取和设置时需要将它们打包到NSNumbers中并从中解压缩.
此外,您无法调用[self setValue:ForKey:];或[self valueForKey:@""];因为这会导致您所处的方法调用自身并使您进入无限循环.Core Data解决了这个用例,它允许您通过调用[self setPrimitiveValue:ForKey:]和来获取和设置值而无需访问您自己的实现[self primiveValueForKey:].注意: primiteValueForKey与基本类型(int,float,BOOL)无关,但它只是用于直接获取和设置Core Data中的值的方法的名称.
你的float和BOOL的实现看起来像这样:
- (float)myFloat
{
[self willAccessValueForKey:@"myFloat"];
float f = [[self primitiveValueForKey:@"myFloat"] floatValue];
[self didAccessValueForKey:@"myFloat"];
return f;
}
- (void)setMyFloat:(float)f
{
[self willChangeValueForKey:@"myFloat"];
[[self setPrimitiveValue:[NSNumber numberWithFloat:f] forKey:@"myFloat"];
[self didChangeValueForKey:@"myFloat"];
}
- (BOOL)isMyBool
{
[self willAccessValueForKey:@"myBool"];
BOOL b = [[self primitiveValueForKey:@"myBool"] boolValue];
[self didAccessValueForKey:@"myBool"];
return b;
}
- (void)setMyBool:(BOOL)b
{
[self willChangeValueForKey:@"myBool"];
[[self setPrimitiveValue:[NSNumber numberWithBool:b] forKey:@"myBool"];
[self didChangeValueForKey:@"myBool"];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1838 次 |
| 最近记录: |