0

I retain a socket in a singleton class like following:

SocketConnection.h

@interface SocketConnection : NSObject

+ (GCDAsyncSocket *) getInstance;

@end

SocketConnection.m

#define LOCAL_CONNECTION 1

#if LOCAL_CONNECTION
#define HOST @"localhost"
#define PORT 5678
#else
#define HOST @"foo.abc"
#define PORT 5678
#endif

static GCDAsyncSocket *socket;

@implementation SocketConnection

+ (GCDAsyncSocket *)getInstance
{
    @synchronized(self) {
        if (socket == nil) {
            dispatch_queue_t mainQueue = dispatch_get_main_queue();
            socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
        }
        if (![socket isConnected]) {

            NSString *host = HOST;
            uint16_t port = PORT;
            NSError *error = nil;

            if (![socket connectToHost:host onPort:port error:&error])
            {
                NSLog(@"Error connecting: %@", error);
            }
        }
    }

    return socket;
}

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"socket connected");
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    NSLog(@"socketDidDisconnect:%p withError: %@", sock, err);
}

@end

And in a viewController:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        _socket = [SocketConnection getInstance];
    }
    return self;
}

I can see that the socket is connected in my server, but there is nothing in my xcode console log. Please help to see why it cannot invoke the delegate method?

goofansu
  • 2,277
  • 3
  • 30
  • 48

1 Answers1

0

You are initializing the socket in SocketConnection's getInstance method, at which point you set the delegate to self. self refers to the SocketConnection instance, not your view controller. Either initialize the socket in the view controller (at which point it's not a singleton anymore), or create a delegate property on SocketConnection and pass delegate methods on to SocketConnection's delegate. Personally, I do the latter, but I send out notifications as opposed to delegate messages.

Scott Berrevoets
  • 16,921
  • 6
  • 59
  • 80
  • Thank you. I prefer to send out notifications. Will my singleton class very large as it will receive every notification. Did you mean addObserver in my singleton class like following? `[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(login) name:@"event_login" object:nil];` – goofansu Oct 09 '12 at 03:27
  • I think get the point. I should dispatch different notification to different class. – goofansu Oct 09 '12 at 03:28
  • Yes, you don't observe notifications in your singleton, you post them. Anyone who subscribes (usually your active view controller) to these notifications will be notified then. – Scott Berrevoets Oct 09 '12 at 04:02
  • Hey @Scott, another question. I moved all socket delegate methods to my socket singleton, and in viewController send data with `[[SocketConnection getInstance] writeData:data withTimeout:-1 tag:-1]`, but the delegate methods cannot be invoked. Is there something wrong? – goofansu Oct 09 '12 at 04:19