iosobjective-csocketsgrand-central-dispatchgcdasyncsocket

GCDAsyncSocket freezes UI when receiving data


I'm new to GCD principles and GCDAsyncSocket, but I'm using it in my project. I initialize the GCD socket in the AppDelegate with:

self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

Now, everything runs fine, sending and receiving works fine. But, if the socket receives a lot of data very fast (like a 1000 or so messages from a 'for loop' from the server), the app's UI freezes till it has received everything (Although there are no errors in the received messages).

So what do I need to change to not let the UI freeze? Is it because it is using "dispatch_get_main_queue()", do I need to use another queue? if so, how should I go about it? Or do I use threading or something like that?


Solution

  • Try creating your own concurrent serial background queue (turns out your not allowed to use a concurrent one), for example

    dispatch_queue_t queue = dispatch_queue_create("com.yourid.queue", DISPATCH_QUEUE_SERIAL);
    self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue: queue];
    

    Alternatively you can pass 'NULL' and GCDAsyncSocket will create its own queue.

    This should call the delegate methods in a background queue and hopefully stop your UI from freezing. The important thing to note here is, you can't update UI Elements on a background queue, so you have to do something like this in your delegate methods:

    - (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port
    {
        //Do some calculations (in background queue)
    
        dispatch_async(dispatch_get_main_queue(), ^{
            //Update UI elements (in main queue)
        });
    } 
    

    (I hope I remembered this correctly)