I'm getting this exc_bad_access error. I did some research into this error and this error means I'm over releasing something but I don't know what I'm over releasing. I think it's something to do with the NSMutableArray that I have in the code. If I comment out the following line, I don't get the error but I don't get any data from core data either.
Here's my complete QuizViewController.h code:
And here's my QuizViewController.m code
Code:
self.quizzes = [[managedObjectContext_ executeFetchRequest:request error:&error] mutableCopy];
Here's my complete QuizViewController.h code:
Code:
@protocol QuizViewControllerDelegate;
@interface QuizViewController : UIViewController {
id <QuizViewControllerDelegate> delegate;
IBOutlet UIImageView *image;
IBOutlet UILabel *questionNumber;
IBOutlet UILabel *question;
IBOutlet UILabel *solution;
IBOutlet UIButton *answerA;
IBOutlet UIButton *answerB;
IBOutlet UIButton *answerC;
IBOutlet UIButton *answerD;
IBOutlet UIButton *next;
NSInteger counter;
NSInteger correctCounter;
NSManagedObjectContext *managedObjectContext_;
NSMutableArray *quizzes;
Quiz *currentQuiz;
}
@property (nonatomic, assign) id <QuizViewControllerDelegate> delegate;
@property (nonatomic, retain) UIImageView *image;
@property (nonatomic, retain) UILabel *questionNumber;
@property (nonatomic, retain) UILabel *question;
@property (nonatomic, retain) UILabel *solution;
@property (nonatomic, retain) UIButton *answerA;
@property (nonatomic, retain) UIButton *answerB;
@property (nonatomic, retain) UIButton *answerC;
@property (nonatomic, retain) UIButton *answerD;
@property (nonatomic, retain) UIButton *next;
@property (nonatomic, assign) NSInteger counter;
@property (nonatomic, assign) NSInteger correctCounter;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext_;
@property (nonatomic, retain) NSMutableArray *quizzes;
@property (nonatomic, readonly) Quiz *currentQuiz;
- (IBAction)done:(id)sender;
- (IBAction)checkAnswer:(id)sender;
- (IBAction)nextQuestion:(id)sender;
- (void)exitQuizOnError;
- (void)completeQuizAlert;
@end
@protocol QuizViewControllerDelegate
- (void)quizViewControllerDidFinish:(QuizViewController *)quiz;
@end
And here's my QuizViewController.m code
Code:
@implementation QuizViewController
@synthesize delegate;
@synthesize image;
@synthesize questionNumber, solution, question;
@synthesize answerA, answerB, answerC, answerD, next;
@synthesize counter, correctCounter;
@synthesize managedObjectContext_;
@synthesize quizzes;
- (Quiz *) currentQuiz {
if (self.counter < 0) {
return nil;
}
Quiz *quiz = [self.quizzes objectAtIndex:(self.counter - 1)];
return quiz;
}
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
counter = 1;
correctCounter = 1;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
//this is needed because QuizViewController isn't the first level view. The managedObjectContext was nil before this declaration
if (self.managedObjectContext_ == nil) {
self.managedObjectContext_ = [(OntarioG1TestAppDelegate *)[[UIApplication sharedApplication] delegate]managedObjectContext];
}
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Quiz"
inManagedObjectContext:managedObjectContext_];
[request setEntity:entity];
NSError *error;
self.quizzes = [[managedObjectContext_ executeFetchRequest:request error:&error] mutableCopy];
[request release];
[self nextQuestion:self];
[super viewDidLoad];
}
-(IBAction)done:(id)sender {
NSLog(@"done");
[self.delegate quizViewControllerDidFinish:self];
}
-(IBAction)checkAnswer:(id)sender{
if (counter==20) {
[self completeQuizAlert];
} else {
NSString *tempSolution;
NSString *tempCorrect = @"Yes, you're right! The answer is: \n";
NSString *tempWrong = @"No, the correct answer is: \n";
NSString *finalSolution;
UIButton *button = (UIButton *)sender;
if ([self.currentQuiz.solution intValue] == 1) {
tempSolution = self.currentQuiz.answerA;
} else if ([self.currentQuiz.solution intValue] == 2) {
tempSolution = self.currentQuiz.answerB;
} else if ([self.currentQuiz.solution intValue] == 3) {
tempSolution = self.currentQuiz.answerC;
} else {
tempSolution = self.currentQuiz.answerD;
}
if ([self.currentQuiz.solution intValue] == button.tag) {
finalSolution = [[NSString alloc] initWithFormat:@"%@ %@", tempCorrect, tempSolution];
correctCounter++;
} else {
finalSolution = [[NSString alloc] initWithFormat:@"%@ %@", tempWrong, tempSolution];
}
solution.text = finalSolution;
[tempSolution release];
[tempCorrect release];
[tempWrong release];
[finalSolution release];
answerA.hidden = YES;
answerB.hidden = YES;
answerC.hidden = YES;
answerD.hidden = YES;
next.hidden = NO;
solution.hidden = NO;
counter++;
NSString *temp = [[NSString alloc]initWithFormat:@"Q: %i/20", counter];
questionNumber.text = temp;
[temp release];
}
}
-(IBAction)nextQuestion:(id)sender{
if ([self.currentQuiz.images isEqualToString:@""]) {
self.question.frame = CGRectMake(self.question.frame.origin.x, 30, self.question.frame.size.width, 130);
self.answerA.frame = CGRectMake(self.question.frame.origin.x, 133, self.question.frame.size.width, 60);
self.answerB.frame = CGRectMake(self.question.frame.origin.x, 201, self.question.frame.size.width, 60);
self.answerC.frame = CGRectMake(self.question.frame.origin.x, 269, self.question.frame.size.width, 60);
self.answerD.frame = CGRectMake(self.question.frame.origin.x, 337, self.question.frame.size.width, 60);
image.hidden = YES;
} else {
self.question.frame = CGRectMake(self.question.frame.origin.x, 190, self.question.frame.size.width, 65);
self.answerA.frame = CGRectMake(self.question.frame.origin.x, 253, self.question.frame.size.width, 45);
self.answerB.frame = CGRectMake(self.question.frame.origin.x, 306, self.question.frame.size.width, 45);
self.answerC.frame = CGRectMake(self.question.frame.origin.x, 359, self.question.frame.size.width, 45);
self.answerD.frame = CGRectMake(self.question.frame.origin.x, 412, self.question.frame.size.width, 45);
image.hidden = NO;
//[images setImage:self.currentQuiz.images];
}
question.text = self.currentQuiz.question;
[answerA setTitle:self.currentQuiz.answerA forState:UIControlStateNormal];
[answerB setTitle:self.currentQuiz.answerB forState:UIControlStateNormal];
[answerC setTitle:self.currentQuiz.answerC forState:UIControlStateNormal];
[answerD setTitle:self.currentQuiz.answerD forState:UIControlStateNormal];
answerA.hidden = NO;
answerB.hidden = NO;
answerC.hidden = NO;
answerD.hidden = NO;
next.hidden = YES;
solution.hidden = YES;
}
#pragma mark -
#pragma mark Alert
-(void)exitQuizOnError {
UIAlertView *alertDialog = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"An error occurred with the quiz. Please restart the quiz."
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alertDialog show];
[alertDialog release];
}
-(void)completeQuizAlert {
UIAlertView *alertDialog;
NSString *tempMessage;
if (correctCounter < 16) {
tempMessage = [[NSString alloc] initWithFormat:@"Sorry you've failed your test. Your score is %i/20. Do you want to try again?", correctCounter];
} else {
tempMessage = [[NSString alloc] initWithFormat:@"Congratulations!! You passed your test. Your score is %i/20. Do you want to try again?", correctCounter];
}
alertDialog = [[UIAlertView alloc]
initWithTitle:@"Quiz Completed!"
message: tempMessage
delegate:self
cancelButtonTitle:@"Yes"
otherButtonTitles:@"No", nil];
[alertDialog show];
[alertDialog release];
[tempMessage release];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0)
{
counter = 1;
questionNumber.text = @"Q: 1/20";
}
else {
[self done:self];
}
}
#pragma mark -
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[image release];
[questionNumber release];
[question release];
[solution release];
[answerA release];
[answerB release];
[answerC release];
[answerD release];
[next release];
[managedObjectContext_ release];
[quizzes release];
[super dealloc];
}
@end