Declare new methods.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1083 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Andrew McCallum 1996-03-07 00:29:05 +00:00
parent b0645f6d52
commit 8e27da11da
2 changed files with 162 additions and 106 deletions

View file

@ -30,7 +30,7 @@
This implementation has several advantages over OpenStep's
NSNotificationCenter:
(1) Heavier use of hash tables and the use of LinkedList's make it
(1) Heavy use of hash tables and the use of LinkedList's make it
faster. Removing from the middle of LinkedList's is much more
efficient than removing from the middle of Array's.
@ -38,15 +38,19 @@
invocation objects instead of just selectors. Invocation objects
are more flexible than selectors in that they can hold more context
and, if desired, can call C functions instead of sending a message
to an object, (this way you may be able to avoid creating a new
to an object; (this way you may be able to avoid creating a new
class just to handle certain notifications).
(3) Instead of sending +defaultCenter, you can simply send -add...,
-remove... and -post... messages directly to the class object.
(3) Instead of sending +defaultCenter, you can simply send +add...,
+remove... and +post... messages directly to the class object.
The class uses a static variable directly, instead of taking
the time for the extra +defaultCenter method call. It's both
easier for the user and more time efficient.
(4) You can call -addObserver:... with both name and object being
nil. This request will receive postings of *all* notifications.
Wow.
Although it offers extra features, the implementation has an
OpenStep-style interface also.
@ -54,68 +58,73 @@
#include <objects/stdobjects.h>
#include <objects/LinkedList.h>
#include <objects/Array.h>
#include <Foundation/NSMapTable.h>
#include <objects/NSString.h>
@interface NotificationDispatcher : NSObject
{
/* For those observer requests with NAME=nil and OBJECT=nil. */
LinkedList *anonymous_nr_list;
/* For those observer requests with NAME=nil and OBJECT!=nil. */
NSMapTable *object_2_nr_list;
/* For those observer requests with NAME!=nil, OBJECT may or may not =nil .*/
NSMapTable *name_2_nr_list;
/* The keys are observers; the values are Array's containing all
NotificationInvocation objects associated with the observer key. */
NSMapTable *observer_2_nr_array;
/* `nr' stands for Notification Request Object; the interface for
this class is defined in the .m file. One of these is created
for each -add... call. */
/* For those observer requests with NAME=nil and OBJECT=nil. */
LinkedList *_anonymous_nr_list;
/* For those observer requests with NAME=nil and OBJECT!=nil. */
NSMapTable *_object_2_nr_list;
/* For those observer requests with NAME!=nil, OBJECT may or may not =nil .*/
NSMapTable *_name_2_nr_list;
/* The keys are observers; the values are Array's containing all
NotificationInvocation objects associated with the observer key. */
NSMapTable *_observer_2_nr_array;
}
/* Adding new observers. */
/* Register observer to receive future notifications that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a wild-card.
If NAME is nil, send to the observer all notification pertaining to
OBJECT. If OBJECT is nil, send to the observer all notification
pertaining to NAME. If both OBJECT and NAME are nil, send to the
observer all notifications.
/* Register INVOCATION to receive future notifictions that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a
wild-card. If NAME is nil, the NotificationDispatcher will send to
the observer all notification pertaining to OBJECT. If OBJECT is
nil, the NotificationDispatcher will send to the observer all
notification pertaining to NAME. If both OBJECT and NAME are nil,
send to the observer all notifications.
The notification will be posted by sending -invokeWithObject: to
INVOCATION argument. The argument of -invokeWithObject: will be
a Notification object. This use of Invocation objects is more
The notification will be posted by sending -invokeWithObject: to
INVOCATION argument. The argument of -invokeWithObject: will be a
Notification object. This use of Invocation objects is more
flexible than using a selector, since Invocation's can be set up
with more arguments, hold more context, and can be C functions.
Typically, in cases that INVOCATION is a MethodInvocation, the
target of INVOCATION will the OBSERVER, but this is not required.
When OBSERVER is not the same as the target, and is non-nil, it can
still be useful for organizational help in removing a coherent set
of observation requests, when used as an argument to -removeObserver:.
Neither OBSERVER nor OBJECT are retained; this is so these objects
can tell when there are no outstanding non-notification references
remaining. If an object may have added itself as an observer, it
should call +removeObserver: in its -dealloc method.
OBJECT is not retained; this is done so these objects can tell when
there are no outstanding non-notification references remaining. If
an object may have added itself as an observer, it should call
+removeObserver: in its -dealloc method.
INVOCATION and NAME, however, are retained. */
- (void) addObserver: observer
invocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
- (void) addInvocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
/* For those that want the simplicity of specifying a selector instead of
an invocation as a way to contact the observer.
/* Register OBSERVER to receive future notifications that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a
wild-card. If NAME is nil, the NotificationDispatcher will send to
the observer all notification pertaining to OBJECT. If OBJECT is
nil, the NotificationDispatcher will send to the observer all
notification pertaining to NAME. If both OBJECT and NAME are nil,
send to the observer all notifications.
The notification will be posted by sending -perform:withObject:
to the observer, with SEL and OBJECT as arguments.
to the observer, with SEL and a Notification object as arguments.
Comments above about retaining apply here also. */
Neither OBSERVER nor OBJECT are retained; this is done so these
objects can tell when there are no outstanding non-notification
references remaining. If an object may have added itself as an
observer, it should call +removeObserver: in its -dealloc method.
INVOCATION and NAME, however, are retained. */
- (void) addObserver: observer
selector: (SEL)sel
@ -125,10 +134,9 @@
/* Class versions of the above two methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) addObserver: observer
invocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
+ (void) addInvocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
+ (void) addObserver: observer
selector: (SEL)sel
name: (id <String>)name
@ -138,21 +146,38 @@
/* Removing observers. */
/* Remove all notification requests that would be sent to INVOCATION. */
- (void) removeInvocation: invocation;
/* Remove the notification requests matching NAME and OBJECT that
would be sent to INVOCATION. As with adding an observation
request, nil NAME or OBJECT act as wildcards. */
- (void) removeInvocation: invocation
name: (id <String>)name
object: object;
/* Remove all records pertaining to OBSERVER. For instance, this
should be called before the OBSERVER is -dealloc'ed. */
- (void) removeObserver: observer;
/* Remove the notification requests for the given parameters. As with
adding an observation request, nil NAME or OBJECT act as wildcards. */
/* Remove the notification requests for the given NAME and OBJECT
parameters. As with adding an observation request, nil NAME or
OBJECT act as wildcards. */
- (void) removeObserver: observer
name: (id <String>)name
object: object;
/* Class versions of the above two methods that send these messages
/* Class versions of the above four methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) removeInvocation: invocation;
+ (void) removeInvocation: invocation
name: (id <String>)name
object: object;
+ (void) removeObserver: observer;
+ (void) removeObserver: observer
name: (id <String>)name
@ -160,16 +185,19 @@
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT. */
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT.
The INFO arguent does not have to be a Dictionary. If there is a single
object that should be associated with the notification, you can simply
pass that single object instead of a Dictionary containing the object. */
- (void) postNotification: notification;
- (void) postNotificationName: (id <String>)name
object: object;
- (void) postNotificationName: (id <String>)name
object: object
userInfo: (id <ConstantKeyedCollecting>)info_dictionary;
userInfo: info;
/* Class versions of the above two methods that send these messages
/* Class versions of the above three methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) postNotification: notification;
@ -177,7 +205,7 @@
object: object;
+ (void) postNotificationName: (id <String>)name
object: object
userInfo: (id <ConstantKeyedCollecting>)info_dictionary;
userInfo: info;
@end

View file

@ -30,7 +30,7 @@
This implementation has several advantages over OpenStep's
NSNotificationCenter:
(1) Heavier use of hash tables and the use of LinkedList's make it
(1) Heavy use of hash tables and the use of LinkedList's make it
faster. Removing from the middle of LinkedList's is much more
efficient than removing from the middle of Array's.
@ -38,15 +38,19 @@
invocation objects instead of just selectors. Invocation objects
are more flexible than selectors in that they can hold more context
and, if desired, can call C functions instead of sending a message
to an object, (this way you may be able to avoid creating a new
to an object; (this way you may be able to avoid creating a new
class just to handle certain notifications).
(3) Instead of sending +defaultCenter, you can simply send -add...,
-remove... and -post... messages directly to the class object.
(3) Instead of sending +defaultCenter, you can simply send +add...,
+remove... and +post... messages directly to the class object.
The class uses a static variable directly, instead of taking
the time for the extra +defaultCenter method call. It's both
easier for the user and more time efficient.
(4) You can call -addObserver:... with both name and object being
nil. This request will receive postings of *all* notifications.
Wow.
Although it offers extra features, the implementation has an
OpenStep-style interface also.
@ -54,68 +58,73 @@
#include <objects/stdobjects.h>
#include <objects/LinkedList.h>
#include <objects/Array.h>
#include <Foundation/NSMapTable.h>
#include <objects/NSString.h>
@interface NotificationDispatcher : NSObject
{
/* For those observer requests with NAME=nil and OBJECT=nil. */
LinkedList *anonymous_nr_list;
/* For those observer requests with NAME=nil and OBJECT!=nil. */
NSMapTable *object_2_nr_list;
/* For those observer requests with NAME!=nil, OBJECT may or may not =nil .*/
NSMapTable *name_2_nr_list;
/* The keys are observers; the values are Array's containing all
NotificationInvocation objects associated with the observer key. */
NSMapTable *observer_2_nr_array;
/* `nr' stands for Notification Request Object; the interface for
this class is defined in the .m file. One of these is created
for each -add... call. */
/* For those observer requests with NAME=nil and OBJECT=nil. */
LinkedList *_anonymous_nr_list;
/* For those observer requests with NAME=nil and OBJECT!=nil. */
NSMapTable *_object_2_nr_list;
/* For those observer requests with NAME!=nil, OBJECT may or may not =nil .*/
NSMapTable *_name_2_nr_list;
/* The keys are observers; the values are Array's containing all
NotificationInvocation objects associated with the observer key. */
NSMapTable *_observer_2_nr_array;
}
/* Adding new observers. */
/* Register observer to receive future notifications that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a wild-card.
If NAME is nil, send to the observer all notification pertaining to
OBJECT. If OBJECT is nil, send to the observer all notification
pertaining to NAME. If both OBJECT and NAME are nil, send to the
observer all notifications.
/* Register INVOCATION to receive future notifictions that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a
wild-card. If NAME is nil, the NotificationDispatcher will send to
the observer all notification pertaining to OBJECT. If OBJECT is
nil, the NotificationDispatcher will send to the observer all
notification pertaining to NAME. If both OBJECT and NAME are nil,
send to the observer all notifications.
The notification will be posted by sending -invokeWithObject: to
INVOCATION argument. The argument of -invokeWithObject: will be
a Notification object. This use of Invocation objects is more
The notification will be posted by sending -invokeWithObject: to
INVOCATION argument. The argument of -invokeWithObject: will be a
Notification object. This use of Invocation objects is more
flexible than using a selector, since Invocation's can be set up
with more arguments, hold more context, and can be C functions.
Typically, in cases that INVOCATION is a MethodInvocation, the
target of INVOCATION will the OBSERVER, but this is not required.
When OBSERVER is not the same as the target, and is non-nil, it can
still be useful for organizational help in removing a coherent set
of observation requests, when used as an argument to -removeObserver:.
Neither OBSERVER nor OBJECT are retained; this is so these objects
can tell when there are no outstanding non-notification references
remaining. If an object may have added itself as an observer, it
should call +removeObserver: in its -dealloc method.
OBJECT is not retained; this is done so these objects can tell when
there are no outstanding non-notification references remaining. If
an object may have added itself as an observer, it should call
+removeObserver: in its -dealloc method.
INVOCATION and NAME, however, are retained. */
- (void) addObserver: observer
invocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
- (void) addInvocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
/* For those that want the simplicity of specifying a selector instead of
an invocation as a way to contact the observer.
/* Register OBSERVER to receive future notifications that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a
wild-card. If NAME is nil, the NotificationDispatcher will send to
the observer all notification pertaining to OBJECT. If OBJECT is
nil, the NotificationDispatcher will send to the observer all
notification pertaining to NAME. If both OBJECT and NAME are nil,
send to the observer all notifications.
The notification will be posted by sending -perform:withObject:
to the observer, with SEL and OBJECT as arguments.
to the observer, with SEL and a Notification object as arguments.
Comments above about retaining apply here also. */
Neither OBSERVER nor OBJECT are retained; this is done so these
objects can tell when there are no outstanding non-notification
references remaining. If an object may have added itself as an
observer, it should call +removeObserver: in its -dealloc method.
INVOCATION and NAME, however, are retained. */
- (void) addObserver: observer
selector: (SEL)sel
@ -125,10 +134,9 @@
/* Class versions of the above two methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) addObserver: observer
invocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
+ (void) addInvocation: (id <Invoking>)invocation
name: (id <String>)name
object: object;
+ (void) addObserver: observer
selector: (SEL)sel
name: (id <String>)name
@ -138,21 +146,38 @@
/* Removing observers. */
/* Remove all notification requests that would be sent to INVOCATION. */
- (void) removeInvocation: invocation;
/* Remove the notification requests matching NAME and OBJECT that
would be sent to INVOCATION. As with adding an observation
request, nil NAME or OBJECT act as wildcards. */
- (void) removeInvocation: invocation
name: (id <String>)name
object: object;
/* Remove all records pertaining to OBSERVER. For instance, this
should be called before the OBSERVER is -dealloc'ed. */
- (void) removeObserver: observer;
/* Remove the notification requests for the given parameters. As with
adding an observation request, nil NAME or OBJECT act as wildcards. */
/* Remove the notification requests for the given NAME and OBJECT
parameters. As with adding an observation request, nil NAME or
OBJECT act as wildcards. */
- (void) removeObserver: observer
name: (id <String>)name
object: object;
/* Class versions of the above two methods that send these messages
/* Class versions of the above four methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) removeInvocation: invocation;
+ (void) removeInvocation: invocation
name: (id <String>)name
object: object;
+ (void) removeObserver: observer;
+ (void) removeObserver: observer
name: (id <String>)name
@ -160,16 +185,19 @@
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT. */
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT.
The INFO arguent does not have to be a Dictionary. If there is a single
object that should be associated with the notification, you can simply
pass that single object instead of a Dictionary containing the object. */
- (void) postNotification: notification;
- (void) postNotificationName: (id <String>)name
object: object;
- (void) postNotificationName: (id <String>)name
object: object
userInfo: (id <ConstantKeyedCollecting>)info_dictionary;
userInfo: info;
/* Class versions of the above two methods that send these messages
/* Class versions of the above three methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) postNotification: notification;
@ -177,7 +205,7 @@
object: object;
+ (void) postNotificationName: (id <String>)name
object: object
userInfo: (id <ConstantKeyedCollecting>)info_dictionary;
userInfo: info;
@end