2010-11-21 68 views
7

我試圖獲取我的實體「MeterReading」,它有兩個屬性,「時間戳」和「閱讀」的結果。 「時間戳」是一個NSDate。我現在試圖用確切的日期獲取對象。使用NSPredicate從NSManagedObjectContect獲取確切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中,我有四個日期條目。如果我使用「< =」而不是「==」,我確實會得到比我通過的日期更小的日期,包括我想要的日期。爲什麼我不能使用「==」運算符獲取單個日期?這可能與我的日期的精確度有關嗎?

謝謝!

回答

3

這與浮點相等檢查本質上是不安全的問題相同。隨着浮點值被傳遞,轉換,用於算術等,它們會逐漸失去準確性。您可能不得不使用更復雜的謂詞,而是在一定的容差範圍內檢查日期;例如,

NSArray *timestamps = [NSArray arrayWithObjects: 
    [self.timestamp dateByAddingTimeInterval:-1], 
    [self.timestamp dateByAddingTimeInterval:1], 
    nil 
]; 

NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp BETWEEN %@", timestamps]; 

這將讓你任何匹配你的日期加或減1秒的任何對象。

+0

幾乎奏效,謝謝!通過數組提出了一個錯誤,但我手動傳遞了兩個nsdates到謂詞,現在它的工作。 :) – denbec 2010-11-22 10:09:31

+0

哎呀,對不起!雖然,很高興幫助。 – 2010-11-22 15:56:54

+0

請注意,此示例不適用於核心數據。你需要使用這樣的東西:http://zdam.posterous.com/core-data-fetch-by-date – SpaceTrucker 2011-11-13 23:33:06

3

第一個問題:爲什麼兩個數字不一樣?

內部,NSDate似乎時間戳相對於存儲到2001年1月1日,而不是1970年1月1號311957172.210091可能是因爲01/01/2001的秒數。

爲什麼我不能用「==」運算符得到單一的日期?這可能與我的日期的精確度有關嗎?

我不知道。您是否直接檢查了SQLite文件以查看哪些時間戳存儲在那裏?

+0

我從我的商店獲取時間戳,將它傳遞給另一個視圖控制器,並嘗試在那裏刪除它。因此我試圖獲取相同的對象;我事先通過了時間戳。這是奇怪的事情。 是否有另一種方法來刪除託管對象,而無需事先獲取該對象? – denbec 2010-11-21 14:44:33

+0

爲什麼你傳遞時間戳而不是對象本身?無需再次獲取它。 – 2010-11-21 15:12:06

1

關於第一個問題,我敢打賭,如果你使用[self.timestamp timeIntervalSinceReferenceDate]代替自1970年以來

關於第二個問題,我的預感是,在管理對象存儲的日期是不完全一樣的號碼將匹配self.timestamp。例如,是否存儲日期只包含一天而不是時間?您可能需要做一些四捨五入的工作才能讓這些匹配。

+0

實際上,我直接從託管對象使用時間戳或日期,將它傳遞給另一個視圖控制器,做一些其他的事情,並希望再次刪除它。因此我需要該對象從上下文中刪除它,並且我不知道任何其他方式在再次獲取對象之前刪除對象。 因此,它應該與我使用的日期相同。 – denbec 2010-11-21 14:41:33