From ca85b74c94dbbbbbb08f71a7ae3abe242e2a5472 Mon Sep 17 00:00:00 2001 From: CaS Date: Fri, 9 Aug 2002 07:43:47 +0000 Subject: [PATCH] Bugfix git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14253 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 6 +++ Source/NSNotificationCenter.m | 92 +++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 630696e08..f176526f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-08-09 Richard Frith-Macdonald + + * Source/NSNotificationCenter.m: ([-postNotification:]) Correct to + post the actual notification we are given rather than a notification + built from that one. Bug report by Alexander Malmberg. + 2002-08-08 Richard Frith-Macdonald * Source/NSProcessInfo.m: ([-globallyUniqueString]) Ensure that the diff --git a/Source/NSNotificationCenter.m b/Source/NSNotificationCenter.m index 605972651..1620fe7cf 100644 --- a/Source/NSNotificationCenter.m +++ b/Source/NSNotificationCenter.m @@ -1,4 +1,5 @@ /** Implementation of NSNotificationCenter for GNUstep + notification = (id)NSAllocateObject(concrete, 0, NSDefaultMallocZone()); Copyright (C) 1999 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald @@ -934,53 +935,26 @@ static NSNotificationCenter *default_center = nil; /** - * Posts notification to all the observers that match its NAME and OBJECT.
- * The GNUstep implementation calls -postNotificationName:object:userInfo: to - * perform the actual posting. + * Private method to perform the actual posting of a notification. + * Release the notification before returning, or before we raise + * any exception ... to avoid leaks. */ -- (void) postNotification: (NSNotification*)notification -{ - [self postNotificationName: [notification name] - object: [notification object] - userInfo: [notification userInfo]]; -} - -/** - * Creates and posts a notification using the - * -postNotificationName:object:userInfo: passing a nil user info argument. - */ -- (void) postNotificationName: (NSString*)name - object: (id)object -{ - [self postNotificationName: name object: object userInfo: nil]; -} - -/** - * The preferred method for posting a notification. - *
- * For performance reasons, we don't wrap an exception handler round every - * message sent to an observer. This means that, if one observer raises - * an exception, later observers in the lists will not get the notification. - */ -- (void) postNotificationName: (NSString*)name - object: (id)object - userInfo: (NSDictionary*)info +- (void) _postAndRelease: (NSNotification*)notification { Observation *o; unsigned count; volatile GSIArray a; unsigned arrayBase; - GSNotification *notification; + NSString *name = [notification name]; + id object; if (name == nil) { + RELEASE(notification); [NSException raise: NSInvalidArgumentException format: @"Tried to post a notification with no name."]; } - notification = (id)NSAllocateObject(concrete, 0, NSDefaultMallocZone()); - name = notification->_name = [name copyWithZone: GSObjCZone(self)]; - object = notification->_object = TEST_RETAIN(object); - notification->_info = TEST_RETAIN(info); + object = TEST_RETAIN([notification object]); if (object != nil) { object = CHEATGC(object); @@ -1207,7 +1181,7 @@ static NSNotificationCenter *default_center = nil; GSIArrayRemoveItemsFromIndex(ARRAY, arrayBase); unlockNCTable(TABLE); - DESTROY(notification); // Get rid of notification we created. + RELEASE(notification); [localException raise]; } NS_ENDHANDLER @@ -1217,6 +1191,52 @@ static NSNotificationCenter *default_center = nil; RELEASE(notification); } + +/** + * Posts notification to all the observers that match its NAME and OBJECT.
+ * The GNUstep implementation calls -postNotificationName:object:userInfo: to + * perform the actual posting. + */ +- (void) postNotification: (NSNotification*)notification +{ + if (notification == nil) + { + [NSException raise: NSInvalidArgumentException + format: @"Tried to post a nil notification."]; + } + [self _postAndRelease: RETAIN(notification)]; +} + +/** + * Creates and posts a notification using the + * -postNotificationName:object:userInfo: passing a nil user info argument. + */ +- (void) postNotificationName: (NSString*)name + object: (id)object +{ + [self postNotificationName: name object: object userInfo: nil]; +} + +/** + * The preferred method for posting a notification. + *
+ * For performance reasons, we don't wrap an exception handler round every + * message sent to an observer. This means that, if one observer raises + * an exception, later observers in the lists will not get the notification. + */ +- (void) postNotificationName: (NSString*)name + object: (id)object + userInfo: (NSDictionary*)info +{ + GSNotification *notification; + + notification = (id)NSAllocateObject(concrete, 0, NSDefaultMallocZone()); + name = notification->_name = [name copyWithZone: GSObjCZone(self)]; + object = notification->_object = TEST_RETAIN(object); + notification->_info = TEST_RETAIN(info); + [self _postAndRelease: notification]; +} + @end @implementation NSNotificationCenter (GNUstep)