ios - 在核心数据中重复 NSDates,但不使用相同代码重复 NSStrings

标签 ios objective-c date core-data nsfetchedresultscontroller

我有一个简单的带有两个选项卡的 TableView Controller 。用户按下加号按钮并以模态方式转到另一个 View Controller 以将文本添加到文本字段并从 UIDatePicker 中选择一个日期。

除了 Core Data 和我的日期存在重复问题外,一切正常。

在应用程序中,第一个 TableView 根据添加到文本字段的条目显示场合,但我已经放入一些代码来检查场合在创建之前是否已经存在。这意味着如果您将“婚礼”作为一个场合并保存,如果您输入另一个以“婚礼”作为场合的条目,而不是在带有婚礼的 TableView 中创建两个单元格,它只创建一个,当您单击在它上面,它是另一个 View Controller 来显示婚礼的所有条目。

效果很好。

但是,当涉及到 UIDatePicker 和选择日期时,会创建重复项。

模型是:

交易实体 场合实体 日期实体

交易实体与场合和日期实体有关系。

让我们看一些代码:

模态视图 Controller 中的保存方法:

- (IBAction)save:(id)sender
{
    NSManagedObjectContext *context = [self managedObjectContext];
    Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
    Occasion *enteredOccasion = (Occasion *)[Occasion occasionWithTitle:self.occasionTextField.text inManagedObjectContext:context];
    transaction.occasion = enteredOccasion;
    // Code to save the date as well - shown below
}

调用 occasionWithTitle 方法进行 NSFetchRequest 检查:

+ (Occasion *)occasionWithTitle:(NSString *)title inManagedObjectContext:(NSManagedObjectContext *)context
{
    Occasion *occasion = nil;

    // Creating a fetch request to check whether the occasion already exists
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Occasion"];
    request.predicate = [NSPredicate predicateWithFormat:@"title = %@", title];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *occasions = [context executeFetchRequest:request error:&error];
    if (!occasions)
    {
        // Handle Error
    }
    else if (![occasions count])
    {
        // If the occasions count is 0 then let's create it
        occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
        occasion.title = title;
    }
    else
    {
        // If the object exists, just return the last object .
        occasion = [occasions lastObject];
    }
    return occasion;
}

日期选择器的代码,也在保存方法中:

Date *date = (Date *)[Date occasionWithDate:self.datePicker.date inManagedObjectContext:context];
transaction.dates = date;

调用:

+ (Date *)occasionWithDate:(NSDate *)enteredDate inManagedObjectContext:(NSManagedObjectContext *)context
{
    Date *date = nil;
    // Creating a fetch request to check whether the date already exists
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Date"];
    request.predicate = [NSPredicate predicateWithFormat:@"dateOfEvent = %@", enteredDate];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"dateOfEvent" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *dates = [context executeFetchRequest:request error:&error];
    if (!dates)
    {
        // Handle Error
    }
    else if (![dates count])
    {
        // If the dates count is 0 then let's create it
        date = [NSEntityDescription insertNewObjectForEntityForName:@"Date" inManagedObjectContext:context];
        date.dateOfEvent = enteredDate;
    }
    else
    {
        // If the object exists, just return the last object .
        date = [dates lastObject];
    }
    return date;
}

对我来说,代码看起来是一样的,但当然一个是传递 NSString,另一个是从 UIDatePicker 传递一个选定的 NSDate。

结果是当涉及到第二个选项卡式表格 View (日期)时,如果我创建一个以 2013 年 12 月 2 日为日期的新事务,然后在 2013 年 12 月 2 日创建另一个条目,它会创建两个单独的单元格同一日期的 TableView ,这当然是不对的。

如能就此令人抓狂的问题提供任何帮助,我们将不胜感激!

编辑:在相关说明中,我将从 DatePicker 中选择日期并将其显示为具有特定格式的 TableView 的部分标题。我正在使用以下代码这样做:

-(NSString *)sectionDateFormatter
{
    return [NSDateFormatter localizedStringFromDate:self.dates.dateOfEvent
                                          dateStyle:NSDateFormatterLongStyle
                                          timeStyle:NSDateFormatterNoStyle];
}

并在 sectionNameKeyPath 中调用它。

最佳答案

好吧,我提供了一个不同的答案,因为你在回复@Tom 时问过你是否应该欺骗字符串来完成这项工作。答案是否定的。

我用 Java 和 Objective-C 进行了大量的日期编程。 Java 的日期内容 (Date/Calendar) 非常蹩脚和不足,首先另一个团队出现了 (Joda-Time),现在它在 8 中完全重做 (JSR 310)。在 Java 中,曾经有一些简单的方法可以用天等来构造事物,但显然,所有这些代码都是在日历的范围之外完成的,所以当语言爆炸时,很快就会发现它一团糟而且没有'' 并导致大量弃用。

然而,在 Cocoa 中,您可以通过使用日期组件来完成所有这些事情。因此,您可以获取一个日期,然后从中提取您感兴趣的组件,然后仅使用这些组件构建另一个日期。这是围绕您不感兴趣的值(例如分钟、秒、毫秒)进行编程的正确方法。

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:6];
[components setMonth:5];
[components setYear:2004];

NSInteger weekday = [components weekday]; 

即使您只是打算进行一些约会编程,也可以考虑观看 WWDC 2013 session 。令人惊讶的是,这不是最好的 session 之一,但它确实涵盖了一些麻烦的事情。

但是日期Date and Time Programming Guide必读,而且非常优秀。

关于ios - 在核心数据中重复 NSDates,但不使用相同代码重复 NSStrings,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20333839/

相关文章:

objective-c - 当前MoviePlayerViewControllerAnimated 的 MPMoviePlayerViewController 问题

ios - 在 websocket/SignalR 响应中获取 "\n "?

ios - 如何以编程方式将 .scn 从 Documents 文件夹转换为 SCNNode?

iphone - 滚动 UITableView 将停止 Timer

ios - 消息传递 - 编译器不会检查方法是否存在?

python - 如何在Python中根据日期的概率生成随机日期?

javascript - 根据日期显示/隐藏 div

ios - 我尝试在两个行星之间创建路径,没有编译错误,但是我不明白为什么模拟器上什么也没有出现

ios - 在 presentViewController 不起作用后调用 pushViewController

java - Java 中的日期和日历(输入字符串)转换和操作