核心数据:不保存
Posted
技术标签:
【中文标题】核心数据:不保存【英文标题】:Core Data: Not saving 【发布时间】:2013-02-21 05:26:44 【问题描述】:我无法保存到一个变量letsMeet.startTimeLabel。选择 NSLog 后立即显示正确的值,但是,在我保存到另一个变量 (letsMeet.endTimeLabel) 后,letsMeet.startTimeLabel 更改为 (NULL)。下面是代码:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:@"LetsMeet" inManagedObjectContext:managedObjectContext];
switch (actionSheet.tag)
case 1:
if (buttonIndex == 0)
UIDatePicker *startDatePicker = (UIDatePicker *)[actionSheet viewWithTag:kDatePickerTag1];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd"];
NSDate *selectedDate = [startDatePicker date];
NSDateFormatter *dayFormatter = [[NSDateFormatter alloc] init];
[dayFormatter setDateFormat:@"EEEE"];
NSDate *selectedDay= [startDatePicker date];
NSDateFormatter *monthFormatter = [[NSDateFormatter alloc] init];
[monthFormatter setDateFormat:@"MMMM"];
NSDate *selectedMonth = [startDatePicker date];
NSString *date = [[NSString alloc] initWithFormat:@"%@", [dateFormatter stringFromDate:selectedDate]];
DateLabel.text = date;
[letsMeet setDateLabel:date];
NSString *month = [[NSString alloc] initWithFormat:@"%@", [dayFormatter stringFromDate:selectedMonth]];
MonthLabel.text = month;
[letsMeet setMonthLabel:month];
NSString *day = [[NSString alloc] initWithFormat:@"%@", [monthFormatter stringFromDate:selectedDay]];
DayLabel.text = day;
[letsMeet setDateLabel:day];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat: @"h:mm a"];
NSDate *selectedStartTime = [startDatePicker date];
NSString *startTime = [[NSString alloc] initWithFormat:@"%@", [timeFormatter stringFromDate:selectedStartTime]];
StartTimeLabel.text = startTime;
[letsMeet setStartTimeLabel:startTime];
NSError *error = nil;
if (![managedObjectContext save:&error])
NSLog(@"Error Saving");
NSLog (@"This is the StartTime after selecting %@", letsMeet.startTimeLabel);
break;
case 2:
if (buttonIndex == 0)
UIDatePicker *endTimePicker = (UIDatePicker *)[actionSheet viewWithTag:kDatePickerTag2];
NSDateFormatter *endTimeFormatter = [[NSDateFormatter alloc] init];
[endTimeFormatter setDateFormat: @"h:mm a"];
NSDate *endSelectedTime = [endTimePicker date];
NSString *endTime = [[NSString alloc] initWithFormat:@"%@", [endTimeFormatter stringFromDate:endSelectedTime]];
EndTimeLabel.text = endTime;
[letsMeet setEndTimeLabel:endTime];
NSLog (@"This is the EndTime %@", letsMeet.endTimeLabel);
NSLog (@"This is the StartTime after selecting BOTH %@", letsMeet.startTimeLabel);
else if (buttonIndex == 1)
EndTimeLabel.text = @"Whenever";
[letsMeet setEndTimeLabel:EndTimeLabel.text];
NSError *error = nil;
if (![managedObjectContext save:&error])
break;
// Handle the error.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
UIViewController *destinationViewController = segue.destinationViewController;
NSLog (@"Prepare For Segue StartTime %@", letsMeet.startTimeLabel);
NSLog (@"Prepare For Segue EndTime%@", letsMeet.endTimeLabel);
这是日志:
2013-02-20 21:38:24.253 AppointmentTime[3129:c07] This is the StartTime after selecting 9:30 AM
2013-02-20 21:38:32.325 AppointmentTime[3129:c07] This is the EndTime 12:15 PM
2013-02-20 21:38:32.325 AppointmentTime[3129:c07] This is the StartTime after Selecting BOTH (null)
2013-02-20 21:38:34.069 AppointmentTime[3129:c07] Prepare For Segue StartTime (null)
2013-02-20 21:38:34.069 AppointmentTime[3129:c07] Prepare For Segue EndTime12:15 PM
问:为什么letsMeet.startTimeLabel第一次显示正确,选择EndTime后变为NULL。请注意,EndTime 一直显示正确的值,直到 prepareForSegue。奇怪!
【问题讨论】:
因为它们是不同的实例。 什么意思?我也为 PrepareForSegue 中的两个变量做了 NSLog,StartTime 显示为 NULL,而 EndTime 显示为正确的值。我更新了代码和日志。 【参考方案1】:根据您的日志和代码,您输入了两次开关块。这意味着您输入了两次actionSheet:clickedButtonAtIndex:
方法。所以每次输入方法
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:@"LetsMeet" inManagedObjectContext:managedObjectContext];
语句执行两次,依次创建两个对象。您可以通过从商店中获取来查看这一点。
因此,您正在检查两个不同对象中的属性,因此检查 null
。
如果您只使用一个托管对象,您可以在执行insertNewObjectForEntityForName:inManagedObjectContext:
之前为该对象添加nil
的检查。这将确保您使用的是相同的对象。
如果您同时使用多个对象,请使用对象 ID 或某个唯一键来识别您的对象并对其进行操作。
编辑: 您可以使用以下代码检查 nil:
if(letsMeet==Nil)
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:@"LetsMeet" inManagedObjectContext:managedObjectContext];
仅当您调用actionSheet:clickedButtonAtIndex:
方法的对象始终在内存中时,这才有效。但是由于您正在坚持,您可能希望从商店中获取对象,然后检查是否。对象。
NSError *error;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"LetsMeet" inManagedObjectContext:managedObjectContext]];
NSArray *objectArray = [managedObjectContext executeFetchRequest:request error:&error]
if(objectArray.count==0)
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:@"LetsMeet" inManagedObjectContext:managedObjectContext];
else
letsMeet = (LetsMeet *)[objectArray objectAtIndex:0];
注意:如果您只需要保留几个变量,那么 core-data 可能就有点过头了。改用 NSUserDefaults 并保持简单。
【讨论】:
感谢您的回复。我只使用一个托管对象。您能否举个例子说明如何检查 nil 以确保我使用的是相同的 managedObject 以及我将它放在哪里? 我试图检查 nil,但它不起作用。我在那个 if 语句中做了一个 NSLog,它永远不会被执行。 StartTime 和 EndTime 的 NSLog 都显示为 NULL。然后我尝试了您的获取代码。同样的事情也会发生。 if 语句中的 NSLog 也永远不会被执行。不知道为什么它跳过了 if 语句。我什至尝试在 ViewDidLoad 中移动这两个代码并得到相同的结果。我应该尝试使用 ObjectID 吗?我不确定如何获得唯一的 ObjectID。谢谢 我还尝试仅将以下行移至 ViewDidLoad:letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:@"LetsMeet" inManagedObjectContext:managedObjectContext];我得到了以下日志: 2013-02-22 09:01:14.632 AppointmentTime[3140:c07] 这是选择 9:01 AM 2013-02-22 09:01:18.409 AppointmentTime[3140:c07] This是 EndTime 12:01 PM 2013-02-22 09:01:18.410 AppointmentTime[3140:c07] 这是选择 BOTH 后的 StartTime(空) 对不起。提供的解决方案有错误..它不是letsMeet!= Nil ..而是letsMeet == Nil。如果变量为 nil,则只创建对象。我会更新答案。 并且在 fetch 部分中,如果它不是 'if' 块,则表示对象数组计数不为零。所以你已经有了一个对象。所以使用那个对象。再次在答案中更新。以上是关于核心数据:不保存的主要内容,如果未能解决你的问题,请参考以下文章