From 6cff7a1fff7d9437cd753bd045fcb8070e56cb83 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Thu, 2 Aug 2007 22:49:50 -0700 Subject: [PATCH] Finally settled on a delegate/notification system combination that works, and is rather clever if I do say so myself. * Source/DebuggerConnection.m: ([DebuggerConnection socketDidAccept]): Changing from a notification receiver to a delegate method * Source/SocketWrapper.h: Making the notification constants not be public * Source/SocketWrapper.m: ([SocketWrapper initWithPort:]): Register the instance of SocketWrapper as a global notification observer ([SocketWrapper setDelegate:]): Removed all occurrences of notification observing ([SocketWrapper _sendMessageToDelegate:]): New function. Receives all notifications and passes up the ones that the object sent (ableit from another thread) to the delegate ([SocketWrapper connect]): Change the type of notification we post ([SocketWrapper _postNotification:withObject:]): Change the key for where we store the delegate in userInfo --- Source/DebuggerConnection.m | 8 ++------ Source/SocketWrapper.h | 3 --- Source/SocketWrapper.m | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/Source/DebuggerConnection.m b/Source/DebuggerConnection.m index 074eb09..5325633 100644 --- a/Source/DebuggerConnection.m +++ b/Source/DebuggerConnection.m @@ -102,13 +102,9 @@ * Called by SocketWrapper after the connection is successful. This immediately calls * -[SocketWrapper receive] to clear the way for communication */ -- (void)socketDidAccept: (NSNotification *)notif +- (void)socketDidAccept { - NSLog(@"accepted %@", notif); - if ([[notif userInfo] objectForKey: SocketWrapperNotificationConnection] == self) - { - NSLog(@"accepted :)"); - } + NSLog(@"accepted :)"); } @end diff --git a/Source/SocketWrapper.h b/Source/SocketWrapper.h index 519756c..2643ddf 100644 --- a/Source/SocketWrapper.h +++ b/Source/SocketWrapper.h @@ -16,9 +16,6 @@ #import -extern NSString *SocketWrapperNotificationConnection; // fancy name for _delegate -extern NSString *SocketDidAcceptNotification; - @interface SocketWrapper : NSObject { int _port; diff --git a/Source/SocketWrapper.m b/Source/SocketWrapper.m index d243564..a74b19b 100644 --- a/Source/SocketWrapper.m +++ b/Source/SocketWrapper.m @@ -21,8 +21,8 @@ #include #include -NSString *SocketWrapperNotificationConnection = @"debuggerconnection"; -NSString *SocketDidAcceptNotification = @"socketdidaccept"; +NSString *sockNotificationDebuggerConnection = @"debuggerconnection"; +NSString *sockDidAcceptNotification = @"socketdidaccept"; @implementation SocketWrapper @@ -34,6 +34,11 @@ NSString *SocketDidAcceptNotification = @"socketdidaccept"; if (self = [super init]) { _port = port; + + // the delegate notifications work funky because of threads. we register ourselves as the + // observer and then pass up the messages that are actually from this object (as we can't only observe self due to threads) + // to our delegate, and not to all delegates + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_sendMessageToDelegate:) name: nil object: nil]; } return self; } @@ -61,14 +66,29 @@ NSString *SocketDidAcceptNotification = @"socketdidaccept"; */ - (void)setDelegate: (id)delegate { - if (_delegate != nil) + _delegate = delegate; +} + +/** + * This is the notification listener for all types of notifications. If the notifications are from a SocketWrapper + * class, it checks that the value of _delegate in the NSNotification's userInfo matches that of this object. If it does, + * then the notification was sent from the same object in another thread and it passes the message along to the object's + * delegate. Complicated enough? + */ +- (void)_sendMessageToDelegate: (NSNotification *)notif +{ + // this isn't us, so there's no point in continuing + if ([[notif userInfo] objectForKey: sockNotificationDebuggerConnection] != _delegate) { - [[NSNotificationCenter defaultCenter] removeObserver: _delegate]; + return; } - _delegate = delegate; + NSString *name = [notif name]; - [[NSNotificationCenter defaultCenter] addObserver: _delegate selector: @selector(socketDidAccept:) name: SocketDidAcceptNotification object: nil]; + if (name == sockDidAcceptNotification) + { + [_delegate socketDidAccept]; + } } /** @@ -130,7 +150,7 @@ NSString *SocketDidAcceptNotification = @"socketdidaccept"; // we're done listening now that we have a connection close(socketOpen); - [self _postNotification: SocketDidAcceptNotification withObject: nil]; + [self _postNotification: sockDidAcceptNotification withObject: nil]; [pool release]; } @@ -221,7 +241,7 @@ NSString *SocketDidAcceptNotification = @"socketdidaccept"; - (void)_postNotification: (NSString *)name withObject: (id)obj { NSDictionary *dict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: _delegate, nil] - forKeys: [NSArray arrayWithObjects: SocketWrapperNotificationConnection, nil]]; + forKeys: [NSArray arrayWithObjects: sockNotificationDebuggerConnection, nil]]; [[NSNotificationCenter defaultCenter] postNotificationName: name object: obj userInfo: dict]; } -- 2.22.5