将NSDate保存到CoreData上下文时出现问题

Ogr*_*amp 8 iphone core-data objective-c ios

我正在尝试使用属性类型Date之一保存托管对象managedObjectContext.

代码如下:

reminder.eventDate = selectedDate;
NSLog(@"Date: %@", selectedDate);
NSError *error = nil;
if (![reminder.managedObjectContext save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
Run Code Online (Sandbox Code Playgroud)

在上下文保存程序中使用SIGABRT崩溃.这是一个控制台日志:

2011-02-28 00:50:18.817 MyApp[9021:207] *** Terminating app due to uncaught 
exception 'NSInvalidArgumentException', reason: '-[__NSDate isEqualToString:]: 
unrecognized selector sent to instance 0x4e73490'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x01057be9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x011ac5c2 objc_exception_throw + 47
    2   CoreFoundation                      0x010596fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00fc9366 ___forwarding___ + 966
    4   CoreFoundation                      0x00fc8f22 _CF_forwarding_prep_0 + 50

有谁知道我为什么这么做?第二个问题是为什么当我在调试器模式下检查时selectedDate不是NSDate类型而是__NSDate(前面是双下划线).

谢谢!

更新:

我做了一些更改,以便更容易地捕获bug.所以代码现在就像:

reminder.eventDate = [NSDate date];
NSLog(@"Date: %@", selectedDate);
NSError *error = nil;
if (![reminder.managedObjectContext save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
Run Code Online (Sandbox Code Playgroud)

所以,在这里我们肯定保存NSDate.reminder.eventDate也是NSDate.但我仍然有这个错误.如果我评论reminder.eventDate = [NSDate date];保存抛出另一个错误(日期是NSData中的必填字段,所以保存:返回错误"操作无法完成." eventDate = nil;.核心数据结构被多次检查 - eventDate具有日期类型.

更新(问题解决):最后我发现了问题.eventDate被设置为detailTextLabel.text我的tableview单元格中的键(我使用了KVO).所以,如果没有直接的电话,我无法找到任何方法调用eventDate.奇怪的是,崩溃是在save方法上,而不是以后.在调用堆栈中根本没有tableView:cellForRowAtIndexPath:方法......

Mas*_*aro 7

听起来很傻,我建议您仔细检查提醒对象和关联的managedObjectContext是否有效.

您确定模型正确地将eventDate建模为日期属性,并且您还确定传递给eventDate属性的对象是NSDate对象.因此,请尝试验证提醒及其managedObjectContext不是nil.

最后,验证是否正确设置了所有其他属性和关系(检查是否实际插入了所有必需的属性和关系,检查您使用的对象是否具有正确的类型等).

这也有助于缩小可能性.

编辑:您可以验证sqlite数据库中实际发生的事情.在开始申请之前,只需添加以下内容作为参数:

-com.apple.CoreData.SQLDebug 1

文档.

如何执行此操作取决于您安装的工具集(Xcode 3或4).我正在使用最新的Xcode 4并添加一个参数,您只需选择当前的方案,然后选择运行"您的应用程序名称"并单击Arguments选项卡以添加参数.


Sim*_*een 6

这听起来好像你的数据模型设置为期望eventDate属性中的字符串,而不是日期.

  • 检查`.xcdatamodel`文件,而不是`.m`文件. (2认同)

Tec*_*Zen 2

只是补充一下已经说过的内容:

这不一定是模型或 NSManagedObject 子类的问题。它可能只是几乎任何调用isEqualToString:. 在某个地方,您有一个对象,代码假定该对象应该是 NSString,但实际上是 NSDate 对象。我会查看任何可能将日期转换为字符串的代码。

但是,由于它发生在保存时,我会查看您可能对子类所做的任何自定义。

首先是在项目中搜索isEqualToString:.

更新:

由于它isEqualToString是一种测试方法,因此可以在对字符串进行比较(例如排序)时随时激活它。我无法重现您的确切错误,但以下代码执行类似的操作:

id idDate=[NSDate date];
NSString *bob=[NSString stringWithString:@"bob"];
NSString *steve=@"test this";
steve=idDate;
NSLog(@"test=%@",([steve compare:bob]) ?@"YES":@"NO");
Run Code Online (Sandbox Code Playgroud)

...符合但抛出异常:

-[NSCFString timeIntervalSinceReferenceDate]: unrecognized selector sent to instance 0x4040
Run Code Online (Sandbox Code Playgroud)

因此,您可以看到这些类型的错误是如何发生的。这也是为什么您应该小心使用id.