2009-11-16 3 views
0

У меня есть три класса, для которых я распространяю NSManagedObject (я знаю, что это не требуется, но я хотел обозначить свойство). Тематические классы - это вопрос, вопрос и ответ. Моя модель данных настроена так, что между ними существует много и много: QuestionSet < < - >> Вопрос < < - >> Ответ. Я загружаю все с сервера, и это успешно сохраняет смысл. Я смотрю в .db-файл, и это все, что я ожидаю, если я сразу же NSLog массивные вопросы, они выглядят великолепно, и если я займусь викториной, это отлично работает.NSLog и основные данные

Однако, если я NSLog этот массив где-нибудь, но сразу после того, как я загружаю их с сервера, это приводит к сбою моего приложения. Тест все еще работает нормально, поэтому я знаю, что данные находятся там и в ожидаемом формате. Это связано с тем, что Core Data очищает пространство, а затем мои отношения не «ленивы загружаются», когда я просто пытаюсь их зарегистрировать? Извините, все еще обернувшись вокруг основных данных.

Этот бит работает, я загружаюсь с сервера, а внизу я загружаю Trivia и записываю то, что получаю. Проблема возникает, если в какой-то момент в ходе выполнения приложения NSLog вопросов будет терпеть неудачу.

- (void)loadQuestionSetFromNetworkWithID:(NSNumber *)p_id andTitle:(NSString *)p_title 
{ 
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:kTriviaQuestionSetURL, [p_id intValue]]]]; 
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; 

NSArray *questions = [[[sbjson objectWithString:json_string error:nil] valueForKeyPath:@"Q"] objectAtIndex:0]; 

NSError *error; 

NSFetchRequest *questionsetRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *questionsetEntity = [NSEntityDescription entityForName:@"QuestionSet" inManagedObjectContext:[self managedObjectContext]]; 
NSPredicate *questionsetPredicate = [NSPredicate predicateWithFormat:@"id = %d", [p_id intValue]]; 

[questionsetRequest setEntity:questionsetEntity]; 
[questionsetRequest setPredicate:questionsetPredicate]; 

QuestionSet *qs = nil; 
NSArray *questionSetObjects = [[self managedObjectContext] executeFetchRequest:questionsetRequest error:&error]; 
if (questionSetObjects == nil){ 
    // Handle errors 
} 
if ([questionSetObjects count] > 0) 
    qs = [questionSetObjects objectAtIndex:0]; 
else 
    qs = [NSEntityDescription insertNewObjectForEntityForName:@"QuestionSet" inManagedObjectContext:[self managedObjectContext]]; 

qs.id = p_id; 
qs.title = p_title; 

for (int i = 0; i < [questions count]; i++) 
{ 
    NSFetchRequest *questionRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *questionEntity = [NSEntityDescription entityForName:@"Question" inManagedObjectContext:[self managedObjectContext]]; 
    NSPredicate *questionPredicate = [NSPredicate predicateWithFormat:@"(id = %d)", [[[questions objectAtIndex:i] objectForKey:@"id"] intValue]]; 

    [questionRequest setEntity:questionEntity]; 
    [questionRequest setPredicate:questionPredicate]; 

    Question *q = nil; 
    NSArray *questionObjects = [[self managedObjectContext] executeFetchRequest:questionRequest error:&error]; 
    if (questionObjects == nil){ 
     // Handle errors 
    } 
    if ([questionObjects count] > 0) 
     q = [questionObjects objectAtIndex:0]; 
    else 
     q = [NSEntityDescription insertNewObjectForEntityForName:@"Question" inManagedObjectContext:[self managedObjectContext]]; 

    q.id = [NSNumber numberWithInt:[[[questions objectAtIndex:i] objectForKey:@"id"] intValue]]; 
    q.question = [[questions objectAtIndex:i] objectForKey:@"text"]; 
    q.answer = [NSNumber numberWithInt:[[[questions objectAtIndex:i] objectForKey:@"ca"] intValue]]; 

    for (int j = 0; j < [[[questions objectAtIndex:i] objectForKey:@"A"] count]; j++) 
    { 
     NSFetchRequest *answerRequest = [[NSFetchRequest alloc] init]; 
     NSEntityDescription *answerEntity = [NSEntityDescription entityForName:@"Answer" inManagedObjectContext:[self managedObjectContext]]; 
     NSPredicate *answerPredicate = [NSPredicate predicateWithFormat:@"(id = %d)", [[[[[questions objectAtIndex:i] objectForKey:@"A"] objectAtIndex:j] objectForKey:@"id"] intValue]]; 

     [answerRequest setEntity:answerEntity]; 
     [answerRequest setPredicate:answerPredicate]; 

     Answer *a = nil; 
     NSArray *answerObjects = [[self managedObjectContext] executeFetchRequest:answerRequest error:&error]; 
     if (answerObjects == nil){ 
      // Handle errors 
     } 
     if ([answerObjects count] > 0) 
      a = [answerObjects objectAtIndex:0]; 
     else 
      a = [NSEntityDescription insertNewObjectForEntityForName:@"Answer" inManagedObjectContext:[self managedObjectContext]]; 

     a.id = [NSNumber numberWithInt:[[[[[questions objectAtIndex:i] objectForKey:@"A"] objectAtIndex:j] objectForKey:@"id"] intValue]]; 
     a.answer = [[[[questions objectAtIndex:i] objectForKey:@"A"] objectAtIndex:j] objectForKey:@"text"]; 

     a.questions = [a.questions setByAddingObject:q]; 
     q.answers = [q.answers setByAddingObject:a]; 

     [answerRequest release]; 
    } 

    q.questionsets = [q.questionsets setByAddingObject:qs]; 
    qs.questions = [qs.questions setByAddingObject:q]; 

    [questionRequest release]; 

} 

[questionsetRequest release]; 

[[self managedObjectContext] save:&error]; 

[json_string release]; 

[self loadTrivia]; 
NSLog(@"After Load: %@", self.questionsets); 
} 

Эта функция извлекает все объекты QuestionSet из db и сохраняет массив в ivar.

- (BOOL)loadTrivia 
{ 
NSError *error; 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"QuestionSet" inManagedObjectContext:[self managedObjectContext]]; 
[request setEntity:entity]; 
self.questionsets = [[self managedObjectContext] executeFetchRequest:request error:&error]; 
return YES; 
} 

Просто для полноты картины, вот мои методы описания в моих классах

из QuestionSet.h

- (NSString *)description 
{ 
return [NSString stringWithFormat:@"\ 
     \n\tid: %@\ 
     \n\ttitle: %@\ 
     \n\tquestions: %@\n", 
     self.id, 
     self.title, 
     self.questions]; 
} 

из Question.h

- (NSString *)description 
{ 
return [NSString stringWithFormat:@"\ 
     \n\tid: %@\ 
     \n\tanswer: %@\ 
     \n\tquestion: %@\ 
     \n\tanswers: %@\n", 
     self.id, 
     self.answer, 
     self.question, 
     self.answers]; 
} 

из Answer.h

- (NSString *)description 
{ 
return [NSString stringWithFormat:@"\ 
     \n\tid: %@\ 
     \n\tanswer: %@\n", 
     self.id, 
     self.answer]; 
} 

ответ

2

Вы не должны наследоваться методом описания (Link):

Хотя метод описания не вызывает неисправность огня, если вы реализуете метод пользовательского описания, который обращается настойчивые свойствами объекта, это будет вызывают пожар. Таким образом, вы категорически отказываетесь от переопределения описания.

Я проверил ваш код loadTrivia (с другим именем entity) в моем приложении, и он работал нормально. ли вы посмотрите на NSError (вы должны инициализировать его = ноль):

NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 

Кроме того, вы должны освободить NSFetchRequest после выполнения в - (BOOL)loadTrivia.

+0

Я бы сказал, что это довольно железный одетый. – rob5408

+0

Извините, больше информации. И loadQuestionSetFromNetworkWithID: andTitle: и loadTrivia: работали для меня, но я положил их там, если кто-то предположил, что моя ошибка была там. Спасибо за помощь! Rob – rob5408

+0

Рад, что я мог помочь. В чем проблема? – FelixLam