I've got a BOOL that seems to change value without being assigned too! However, it only happens when switching between view controllers. Basically I have a TableViewController going to a DetailViewController, the BOOL is on the DetailViewController. It is used to determine whether a timer is currently running. When just staying on the DetailViewController the BOOL works as expected, however when switching between DetailViewController and TableViewController, that's when the problem occurs. In no place on TableViewController is it being assigned to.
I have NSLogged all over the place, I've used lots of breakpoints and also watchpoints on the BOOL itself, however I still can't figure out what's making it change!
Okay, on the viewDidLoad of DetailViewController, the BOOL is updated from a Core Data entity.
- (void)viewDidLoad {
[super viewDidLoad];
// MORE CODE
_running = [[_timerObject valueForKey:@"running"] boolValue];
****_running is NO on initial load**** - expected
****_running is YES when returning to DetailViewController**** - expected
// MORE CODE
}
I then have a button to start/cancel the timer and use the BOOL to toggle the button.
- (IBAction)start:(id)sender {
****_running is NO on first press**** - expected
****_running is YES on second press**** - NOT EXPECTED!?!?!?!
// if timer is running
if (_running) {
// CANCEL TIMER CODE
}
else {
// START TIMER CODE
}
// Update BOOL
_running = !_running;
****_running is YES**** - expected
}
When the timer completes, this method is called.
- (void)timerComplete {
****_running is YES**** - expected
// OTHER CODE HERE
// Cancel timer
[_appDelegate.timerManager stopTimer:_timerID];
// Update BOOL
_running = NO;
****_running is NO**** - expected
// Save to ensure booleans are correct
[self save];
****_running is NO**** - expected
}
My save method looks like this. It is called at the end of timerComplete and also in the viewDidDisappear method.
- (void)save {
// Create variable of managed object context AppDelegate
NSManagedObjectContext *context = [self managedObjectContext];
if (_timerObject) {
// Update existing timer
if ([_nameTextField.text isEqualToString:@""]) {
[_timerObject setValue:@"Timer" forKey:@"name"];
}
else {
[_timerObject setValue:_nameTextField.text forKey:@"name"];
}
[_timerObject setValue:_date forKey:@"timeStart"];
[_timerObject setValue:[NSNumber numberWithBool:_running] forKey:@"running"];
[_timerObject setValue:[NSNumber numberWithBool:_paused] forKey:@"paused"];
//----------------
// Update title of view
self.title = [_timerObject valueForKey:@"name"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}
****_running is NO**** - expected
}
The behaviour required to break it is: - Load DetailViewContoller - Press Start Timer - Go back to TableViewController - Go to DetailViewController - Wait for Timer to Complete - Press Start Timer again and nothing happens because _running is YES, not NO!
I've annotated the code segments with the values of "_running" in various different places.
As far as I can tell, nothing happens between timerComplete and pressing start again so I don't know why the BOOL changes from NO to YES in that time! Any help would be greatly appreciated! :)
Just an extra note NSLog(@"timerObject: %@", [_timerObject valueForKey:@"running"]);
outputs a 0 when placed in the same placed as where _running returns YES in the start timer method! So the core data value appears to be correct, just not _running!