Skip to main content

Problem with saving NSDate to the CoreData context


I'm trying to save managed object with one of the attribute's type Date to the managedObjectContext .



Code is like:




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



during context saving program crashes with SIGABRT. Here is a console log:



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


Does anyone knows why I have that? Second question is why when I check in debugger mode selectedDate isn't NSDate type but __NSDate (double underscore in front).



Thanks!



UPDATE:



I did some changes to easier catch the bug. so code now is like:




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



so, here we save definitely NSDate. reminder.eventDate is NSDate too. But I still have this error. If I comment reminder.eventDate = [NSDate date]; saving throws another error (date is mandatory field in NSData, so save: returns error "The operation couldn’t be completed." with eventDate = nil; . CoreData structure is checked multiple times - eventDate has Date type.



UPDATE (Problem solved): Finally I found the problem. eventDate was set as key for the detailTextLabel.text in my tableview cells (I used KVO for that). So if was no direct call and I wasn't able to find any method invokation for the eventDate . Strange thing is that crash was on the save method, not later. And in the call stack there is no tableView:cellForRowAtIndexPath: method at all...


Source: Tips4all
Source: Tips4allSource: CCNA FINAL EXAM

Comments

  1. Just to add to what has already been said:

    It doesn't have to be a problem with the model or the NSManagedObject subclass. It could just be a piece of code almost anywhere that calls isEqualToString:. Somewhere you've got an object that the code assumes should be a NSString but is instead a NSDate object. I would look at any code that might convert dates to strings.

    However, since it happens upon save I would look at any customizations you might have done to the subclass.

    The place to start is by searching the project for isEqualToString:.

    Update:

    Since isEqualToString is a testing method it can be activated anytime you do a compare for a string such as in a sort. I couldn't reproduce your exact error but the following code does something similar:

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


    ... complies but throws an exception:

    -[NSCFString timeIntervalSinceReferenceDate]: unrecognized selector sent to instance 0x4040


    So, you can see how these types of errors can slip in. It's also a demonstration for why you should be careful with the use of id.

    ReplyDelete
  2. Silly as it sounds, I would suggest that you double check that both your reminder object and associated managedObjectContext are valid.

    You are certain that your model correctly models eventDate as a date attribute, and you are also certain that the object you pass to the eventDate attribute is a NSDate object. So, try verifying that reminder and its managedObjectContext are not nil.

    Finally, verify if all of the other attributes and relations are correctly set (check if you actually insert all of the required attributes and relations, check if the objects you use are of the correct type etc).

    This will also help narrowing the possibilities.

    EDIT: You can verifying what is actually happening inside your sqlite database. Simply add the following as an argument before starting your application:

    -com.apple.CoreData.SQLDebug 1

    see the documentation.

    How you do this depends on your installed toolset (Xcode 3 or 4). I am using the latest Xcode 4 and to add an argument you simply select your current scheme, then you select Run "your app name" and click the Arguments tab to add the argument.

    ReplyDelete
  3. That sounds like you have your data model set up to expect a string in the eventDate property, rather than a date.

    ReplyDelete
  4. NSDate is a "class cluster", which means that instances you actually deal with will be instances of some private subclass of NSDate (in this case, __NSDate).

    As for the error, I agree with Simon Goldeen that the most likely reason is that the data model or the NSManagedObject subclass is expecting a string rather than a date.

    ReplyDelete
  5. I chased this one too. Since your model and class definitions are good, and assuming your value is good, then there's one less obvious place that fixed it for me ... Delete the app from the device and clean your build, and make sure any seeded sqlite files are new too. My device or build folder had an old store or model lingering that caused this. What other frameworks are you using? RestKit, JSON, etc? Anything that overloads a class method could also be a suspect. ... hard to tell whats getting compared in that save ... My guess is an old store

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.