2012-07-20 3 views
3

Я работаю над примером кода из NSScreenCast, который занимается импортом в приложение Core Data. (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, который передается в столбец без данных. Таким образом, он никогда ничего не соответствует. Теперь я просматриваю код, чтобы узнать, могу ли я его найти. В datamodel отображается serverId. –

+0

@MikeRiley, каковы журналы для результатов NSLog (@ ":% @", results); ' & 'NSLog (@ "results objectAtIndex: 0 =% @", [results objectAtIndex: 0]);'? – Kjuly

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

+0

Спасибо за указание это вне. Я всегда использовал двойные равные числа. Документы не лгут. – Jamie

+0

@ Jamie Я всегда тоже .. – Kjuly

1

Вы пытаетесь сравнить скалярное значение (NSInteger) с значением объекта (NSNumber) в своем предикате.

Try:

[NSPredicate predicateWithFormat:@"serverId = %@", [NSNumber numberWithInteger:serverId]] 
Смежные вопросы