2012-07-20 66 views
3

我正在處理從NSScreenCast處理導入到核心數據應用程序的代碼示例。 (https://github.com/subdigital/nsscreencast/tree/master/012-core-data-importing-data/BeerBrowser)。我有大部分工作的例子。我能夠推動刷新按鈕,它解析json並將其導入到數據庫中。但是,每次按刷新按鈕時,都會重新添加相同的數據。我已經將其追溯到下面的代碼。核心數據問題 - 檢查項目是否存在

+ (Brewery *)breweryWithServerId:(NSInteger)serverId usingManagedObjectContext:(NSManagedObjectContext *)moc { 
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Brewery entityName]]; 

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId = %d", serverId]]; 
[fetchRequest setFetchLimit:1]; 

NSError *error = nil; 
NSArray *results = [moc executeFetchRequest:fetchRequest error:&error]; 
NSLog(@"results: %@", results); 
if (error) { 
    NSLog(@"ERROR: %@ %@", [error localizedDescription], [error userInfo]); 
    exit(1); 
} 

if ([results count] == 0) { 
    return nil; 
} 
NSLog(@"results objectAtIndex:0 = %@", [results objectAtIndex:0]); 

return [results objectAtIndex:0]; 
} 

這種方法會發生什麼,它會嘗試查看數據庫中是否已存在該項目。如果此調用返回nil,則MasterViewController中的代碼將其再次添加到數據庫中。我做了一些調試,並且serverId確實通過了。此外,fetchrequest似乎是有效的(無法確切地調試它)。正如你所看到的,我已經爲結果添加了一個NSLog,但它返回一個空的結果。因此,如果結果數爲0,則返回nil。因此我的問題。我沒有看到這個問題可能成爲一個問題。有什麼想法嗎?

邁克 - 萊利

回答

4

我只是修改你的方法,你可以只取一試:

+ (Brewery *)breweryWithServerId:(NSInteger)serverId usingManagedObjectContext:(NSManagedObjectContext *)moc { 
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Brewery entityName]]; 
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId == %d", serverId]]; 
    [fetchRequest setFetchLimit:1]; 

    NSError *error = nil; 

    // if there's no object fetched, return nil 
    if ([managedObjectContext countForFetchRequest:fetchRequest error:&error] == 0) { 
    NSLog(@"!!!WARN: NO Object Matches."); 
    return nil; 
    } 

    // fetch your object 
    Brewery *result = [[moc executeFetchRequest:fetchRequest error:&error] lastObject]; 
    if (error != nil) { 
    NSLog(@"ERROR: %@ %@", [error localizedDescription], [error userInfo]); 
    return nil; 
    } 

    NSLog(@"results objectAtIndex:0 = %@", result); 
    return result; 
} 

注:-countForFetchRequest:error:更有效,因爲它只有「返回對象給定的獲取請求將數量已經返回'。您可以使用此方法來檢查是否有匹配的對象。

+0

感謝您的幫助。我試了一下,仍然得到同樣的問題。在深入挖掘它之後,似乎它正在比較的serverId在任何時候都不會保存到數據庫中。所以setPredicate正在比較傳遞給沒有數據的列的serverId。因此它從不匹配任何東西。我正在查看代碼,看看我能否找到它。數據模型確實顯示serverId。 – 2012-07-20 04:15:45

+0

@MikeRiley'NSLog的日誌是什麼(@「results:%@」,結果);' &'NSLog(@「results objectAtIndex:0 =%@」,[results objectAtIndex:0]);'? – Kjuly 2012-07-20 05:25:51

0

我認爲你的謂詞有問題。它應該閱讀:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId == %d", serverId]]; 

你錯過了雙等於....

發現這並不重要。你應該檢查以確保你的moc不是零。你確定你正確地傳遞了它嗎?

+1

實際上,這不是它 - '='和'=='在'NSPredicate'中是一樣的。點擊此處查看基本比較部分https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-CJBDBHCB – ikuramedia 2012-07-20 04:41:45

+0

感謝您的指點那個。我一直使用double equals。文檔不會撒謊。 – Jamie 2012-07-20 04:49:10

+0

@Jamie我總是太.. – Kjuly 2012-07-20 05:20:00

1

您試圖在謂詞中比較標量值(NSInteger)與對象值(NSNumber)。

嘗試:

[NSPredicate predicateWithFormat:@"serverId = %@", [NSNumber numberWithInteger:serverId]]