我有三个类,我正在扩展NSManagedObject(我知道这不是必需的,但我想要属性表示法)。这些课程是问题集,问题和答案。设置我的数据模型,以便它们之间存在多对多:问题集<< - >>问题<< - >>回答。我从服务器加载所有内容并成功保存意味着我查看.db文件,这就是我所期望的,如果我立即NSLog他们看起来很棒的数组问题集,如果我去参加一个测验它很有用。
但是,如果我在任何地方NSLog那个数组,但在我从服务器加载它们之后,它会崩溃我的应用程序。测验仍然运行正常,所以我知道数据在那里并以预期的格式。这是否与Core Data清除空间有关,然后当我只是尝试登录时,我的关系不会“懒得加载”?对不起,我仍然围绕着核心数据。
这个位工作,我从服务器加载,在底部我'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);
}
此函数从db中获取所有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];
}
答案 0 :(得分:2)
您不应该对描述方法(Link)进行子类化:
尽管描述方法不会导致触发错误,但如果实现访问对象的持久属性的自定义描述方法,则会导致触发错误。强烈建议您不要以这种方式覆盖描述。
我在我的应用上测试了你的loadTrivia代码(使用不同的entityName)并且工作正常。
您是否看过NSError
(您应该使用= nil初始化它):
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
此外,您应该在- (BOOL)loadTrivia
执行后释放NSFetchRequest。