Added -addObserverForName:selector:queue:usingBlock: to NSNotificationCenter

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@37691 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Quentin Mathe 2014-02-14 14:23:09 +00:00
parent 0e7e0d1818
commit e51bd0979d
3 changed files with 136 additions and 2 deletions

View file

@ -1,3 +1,10 @@
2014-02-14 Quentin Mathe <quentin.mathe@gmail.com>
* Headers/Foundation/NSNotification.h
* Source/NSNotificationCenter.m
(-addObserverForName:selector:queue:usingBlock:): Added new Mac OS X 10.6
method.
2014-02-14 Quentin Mathe <quentin.mathe@gmail.com>
* Headers/Foundation/NSSortDescriptor.h

View file

@ -32,6 +32,7 @@
#import <Foundation/NSObject.h>
#import <Foundation/NSMapTable.h>
#import <GNUstepBase/GSBlocks.h>
#if defined(__cplusplus)
extern "C" {
@ -40,6 +41,7 @@ extern "C" {
@class NSString;
@class NSDictionary;
@class NSLock;
@class NSOperationQueue;
@interface NSNotification : NSObject <NSCopying, NSCoding>
@ -59,7 +61,10 @@ extern "C" {
@end
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
DEFINE_BLOCK_TYPE(GSNotificationBlock, void, NSNotification *);
#endif
@interface NSNotificationCenter : NSObject
{
@ -75,6 +80,12 @@ extern "C" {
selector: (SEL)selector
name: (NSString*)name
object: (id)object;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
- (id) addObserverForName: (NSString *)name
object: (id)object
queue: (NSOperationQueue *)queue
usingBlock: (GSNotificationBlock)block;
#endif
- (void) removeObserver: (id)observer;
- (void) removeObserver: (id)observer

View file

@ -35,6 +35,7 @@
#import "Foundation/NSDictionary.h"
#import "Foundation/NSException.h"
#import "Foundation/NSLock.h"
#import "Foundation/NSOperation.h"
#import "Foundation/NSThread.h"
#import "GNUstepBase/GSLock.h"
@ -642,7 +643,93 @@ purgeCollectedFromMapNode(GSIMapTable map, GSIMapNode node)
#define purgeCollectedFromMapNode(X, Y) ((Observation*)Y->value.ext)
#endif
@interface GSNotificationBlockOperation : NSOperation
{
NSNotification *_notification;
GSNotificationBlock _block;
}
- (id) initWithNotification: (NSNotification *)notif
block: (GSNotificationBlock)block;
@end
@implementation GSNotificationBlockOperation
- (id) initWithNotification: (NSNotification *)notif
block: (GSNotificationBlock)block
{
self = [super init];
if (self == nil)
return nil;
ASSIGN(_notification, notif);
_block = Block_copy(block);
return self;
}
- (void) dealloc
{
DESTROY(_notification);
Block_release(_block);
[super dealloc];
}
- (void) main
{
CALL_BLOCK(_block, _notification);
}
@end
@interface GSNotificationObserver : NSObject
{
NSOperationQueue *_queue;
GSNotificationBlock _block;
}
@end
@implementation GSNotificationObserver
- (id) initWithQueue: (NSOperationQueue *)queue
block: (GSNotificationBlock)block
{
self = [super init];
if (self == nil)
return nil;
ASSIGN(_queue, queue);
_block = Block_copy(block);
return self;
}
- (void) dealloc
{
DESTROY(_queue);
Block_release(_block);
[super dealloc];
}
- (void) didReceiveNotification: (NSNotification *)notif
{
if (_queue != nil)
{
GSNotificationBlockOperation *op = [[GSNotificationBlockOperation alloc]
initWithNotification: notif block: _block];
[_queue addOperation: op];
}
else
{
CALL_BLOCK(_block, notif);
}
}
@end
/**
* <p>GNUstep provides a framework for sending messages between objects within
@ -874,6 +961,35 @@ static NSNotificationCenter *default_center = nil;
unlockNCTable(TABLE);
}
/**
* <p>Returns a new observer added to the notification center, in order to
* observe the given notification name posted by an object or any object (if
* the object argument is nil).</p>
*
* <p>For the name and object arguments, the constraints and behavior described
* in -addObserver:name:selector:object: remain valid.</p>
*
* <p>For each notification received by the center, the observer will execute
* the notification block. If the queue is not nil, the notification block is
* wrapped in a NSOperation and scheduled in the queue, otherwise the block is
* executed immediately in the posting thread.</p>
*/
- (id) addObserverForName: (NSString *)name
object: (id)object
queue: (NSOperationQueue *)queue
usingBlock: (GSNotificationBlock)block
{
GSNotificationObserver *observer =
[[GSNotificationObserver alloc] initWithQueue: queue block: block];
[self addObserver: observer
selector: @selector(didReceiveNotification:)
name: name
object: object];
return observer;
}
/**
* Deregisters observer for notifications matching name and/or object. If
* either or both is nil, they act like wildcards. The observer may still