【发布时间】:2023-03-12 17:01:02
【问题描述】:
我有三个要扩展 NSManagedObject 的类(我知道这不是必需的,但我想要属性符号)。论文类是 QuestionSet、Question 和 Answer。我的数据模型已设置好,因此它们之间存在多对多,如下所示: QuestionSet > Question > Answer。我从服务器加载所有内容并成功保存,这意味着我查看 .db 文件,这就是我所期望的,如果我立即 NSLog 数组问题集,它们看起来很棒,如果我去参加测验,效果很好。
但是,如果我在从服务器加载它们之后的任何地方 NSLog 该数组,它会使我的应用程序崩溃。测验仍然运行良好,所以我知道数据在那里并且是预期的格式。这是否与核心数据清理空间有关,然后我的关系在我试图记录它们时不会“延迟加载”?抱歉,我还在纠结核心数据。
这一点有效,我从服务器加载,在底部我“loadTrivia”并记录我得到的内容。如果在应用程序执行过程中稍后的某个时间,问题集的 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 对象并将数组存储在 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];
}
【问题讨论】:
标签: objective-c iphone xcode core-data