Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

stadidas

macrumors regular
Original poster
Feb 27, 2006
243
0
Kent, United Kingdom
In my MyDocument class I have these two methods:

Code:
- (void)setupTimer:(id)sender
{
	timer = [NSTimer scheduledTimerWithTimeInterval:1
											 target:self
										   selector:@selector(updateDatePickers:)
										   userInfo:nil
											repeats:YES];
}

- (void)updateDatePickers:(NSTimer *)aTimer
{
	NSDate *temp = [NSDate date];
	[currentDate setDateValue:temp];
}

setupTimer is called from windowControllerDidLoadNib. My problem is that when I close the window the NSTimer keeps firing the updateDatePickers method, causing the program to crash. I have tried invalidating and releasing the time in my classes dealloc method, but this doesn't work. Doers anyone know how to stop the timer from firing when the window is closed?
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
You need to retain it the first time, or use the passed timer on your action:

Code:
- (void)setupTimer:(id)sender
{
	timer = [[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateDatePickers:) userInfo:nil repeats:YES] retain];
}

- (void)updateDatePickers:(NSTimer *)aTimer
{
	NSDate *temp = [NSDate date];
	[currentDate setDateValue:temp];

	// aTimer is the same timer above, so you can also call [aTimer invalidate] here
}

- (void)stopTimer
{
	[timer invalidate];
	[timer release];
}

- (void)dealloc
{
	[self stopTimer];
	[super dealloc];
}
 

stadidas

macrumors regular
Original poster
Feb 27, 2006
243
0
Kent, United Kingdom
I've made those changes but the program still crashes.
I can't use [aTimer invalidate] in updateDatePickers because I want the timer to keep firing for the life of the window. Even though I have [self stopTimer]; in the dealloc method, GDB still highlights [currentDate setDateValue:temp]; in the updateDatePickers method when the app freezes. I presume that the timer is still firing and calling this method after the window has closed and 'currentDate' is deallocated.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
In the timer action, just check for [[self window] isVisible], and if it's visible, update the GUI. If not, ignore any GUI updates until it's visible again.
 

MongoTheGeek

macrumors 68040
In the timer action, just check for [[self window] isVisible], and if it's visible, update the GUI. If not, ignore any GUI updates until it's visible again.

He still has the problem that he is invoking a method of an object which has been deallocated.

The invalidate in the dealloc should fix it. I was just checking my code and that is all I had to do to handle it.
 

stadidas

macrumors regular
Original poster
Feb 27, 2006
243
0
Kent, United Kingdom
My code looks like this:
Code:
- (void)updateDatePickers:(NSTimer *)aTimer
{
	if ([[self window] isVisible]) {
		NSDate *temp = [NSDate date];
		[currentDate setDateValue:temp];
	}
}

and I get this error in the Xcode terminal:
2006-12-02 18:55:54.719 AssetMonitor[2206] *** NSTimer discarding exception '*** -[MyDocument window]: selector not recognized [self = 0x34ecb0]' that raised during firing of timer with target 34ecb0 and selector 'updateDatePickers:'
I don't know why calling stopTimer in the dealloc method isn't working.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Oops, didn't see the MyDocument part. Change [self window] to [self windowForSheet]
 

stadidas

macrumors regular
Original poster
Feb 27, 2006
243
0
Kent, United Kingdom
Oops, didn't see the MyDocument part. Change [self window] to [self windowForSheet]

Fantastic. I was going to try that earlier but didn't for some reason. It works now though.
The timers not being deallocated is probably causing a memory leak, although I can't imagine them using much memory, so I'm not too worried for now.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.