Make firing of timers more robust

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31420 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2010-09-25 21:28:07 +00:00
parent 6d16a28788
commit 8bd0177292
2 changed files with 45 additions and 24 deletions

View file

@ -1,3 +1,9 @@
2010-09-25 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSTimer.m: ([-fire]) make firing more robust by retaining
the target so it cannot be deallocated while we are performing a
method on it. Do nothing if timer is already invalidated.
2010-09-24 Richard Frith-Macdonald <rfm@gnu.org> 2010-09-24 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSCharacterSet.m: Build using the faster but more memory * Source/NSCharacterSet.m: Build using the faster but more memory

View file

@ -224,36 +224,51 @@ static Class NSDate_class;
*/ */
- (void) fire - (void) fire
{ {
if (_selector == 0) id target;
/* We retain the target so it won't be deallocated while we are using it
* (if this timer gets invalidated while we are firing).
*/
target = [_target retain];
/* We check that we have not been invalidated before we fire.
*/
if (NO == _invalidated)
{ {
NS_DURING if (_selector == 0)
{ {
[(NSInvocation*)_target invoke]; NS_DURING
{
[(NSInvocation*)target invoke];
}
NS_HANDLER
{
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
@"raised during posting of timer with target %p "
@"and selector '%@'",
[localException name], [localException reason], target,
NSStringFromSelector([target selector]));
}
NS_ENDHANDLER
} }
NS_HANDLER else
{ {
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') " NS_DURING
@"raised during posting of timer with target %p and selector '%@'", {
[localException name], [localException reason], _target, [target performSelector: _selector withObject: self];
NSStringFromSelector([_target selector])); }
NS_HANDLER
{
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
@"raised during posting of timer with target %p and "
@"selector '%@'",
[localException name], [localException reason], target,
NSStringFromSelector(_selector));
}
NS_ENDHANDLER
} }
NS_ENDHANDLER
}
else
{
NS_DURING
{
[_target performSelector: _selector withObject: self];
}
NS_HANDLER
{
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
@"raised during posting of timer with target %p and selector '%@'",
[localException name], [localException reason], _target,
NSStringFromSelector(_selector));
}
NS_ENDHANDLER
} }
[target release];
if (_repeats == NO) if (_repeats == NO)
{ {