【问题标题】:Using NSPredicate to fetch exact NSDate from NSManagedObjectContect使用 NSPredicate 从 NSManagedObjectContect 获取准确的 NSDate
【发布时间】:2011-05-13 08:54:37
【问题描述】:

我正在尝试获取我的实体“MeterReading”的结果,它有两个属性,“timestamp”和“reading”。 “时间戳”是一个 NSDate。我现在正在尝试获取具有确切日期的对象。

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MeterReading" inManagedObjectContext:context];
[request setEntity:entity];
NSLog(@"%f", [self.timestamp timeIntervalSince1970]);

NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp == %@", self.timestamp];
NSLog(@"%@", pre);
[request setPredicate:pre];

现在,self.timestamp 被预先传递给另一个 ViewController,NSLog 显示:

1290264372.210091

NSPredicate 日志

时间戳 == CAST(311957172.210091, "NSDate")

第一个问题:为什么这两个数字不一样?

第二个也是更重要的问题:在 ManagedContext 中,我有四个带有日期的条目。如果我使用“

谢谢!

【问题讨论】:

    标签: iphone objective-c nsdate nspredicate fetch


    【解决方案1】:

    这与浮点相等检查本质上是不安全的问题相同。当浮点值被传递、转换、用于算术等时,它们会一点一点地失去准确性。您可能必须使用更复杂的谓词来检查特定容差内的日期;例如,

    NSArray *timestamps = [NSArray arrayWithObjects:
        [self.timestamp dateByAddingTimeInterval:-1],
        [self.timestamp dateByAddingTimeInterval:1],
        nil
    ];
    
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp BETWEEN %@", timestamps];
    

    这将为您提供与您的日期相匹配的任何对象加或减一秒。

    【讨论】:

    • 几乎成功了,谢谢!传递数组引发了一个错误,但我手动将两个 nsdates 传递给谓词,现在它可以工作了。 :)
    • 糟糕,抱歉!不过,很高兴它有所帮助。
    • 请注意,此示例不适用于核心数据。你需要使用这样的东西:zdam.posterous.com/core-data-fetch-by-date
    【解决方案2】:

    对于您的第一个问题,我敢打赌,如果您使用 [self.timestamp timeIntervalSinceReferenceDate] 而不是自 1970 年以来的数字,那么这些数字将会匹配。

    对于第二个问题,我的直觉是托管对象存储中的日期与 self.timestamp 不完全相同。例如,存储的日期是否只包含一天而不包含时间?您可能需要进行一些舍入以使它们匹配。

    【讨论】:

    • 实际上,我直接使用托管对象中的时间戳或日期,将其传递给另一个视图控制器,做一些其他事情并想再次删除它。因此我需要对象从上下文中删除它,并且我不知道在再次获取之前删除对象的任何其他方法。所以,它应该是我使用的同一日期。
    【解决方案3】:

    第一个问题:为什么这两个数字不一样?

    在内部,NSDate 似乎存储相对于 2001 年 1 月 1 日而非 1970 年 1 月 1 日的时间戳。数字 311957172.210091 可能是自 2001 年 1 月 1 日以来的秒数。

    为什么我不能使用“==”运算符获得一个日期?这可能与我的日期精度有关吗?

    我不知道。您是否直接检查了 SQLite 文件以查看其中存储了哪些时间戳?

    【讨论】:

    • 我正在从我的商店获取时间戳,将其传递给另一个视图控制器并尝试将其删除。因此我试图获取相同的对象;我事先通过了时间戳。这就是奇怪的事情。是否有另一种方法可以在不事先获取该对象的情况下删除托管对象?
    • 为什么传递时间戳而不是对象本身?无需再次获取它。
    猜你喜欢
    • 1970-01-01
    • 2011-09-13
    • 2015-10-02
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多