ios - 使用GCDAsyncSocket进行同步通信

标签 ios objective-c grand-central-dispatch cocoaasyncsocket gcdasyncsocket

我正在使用GCDAsyncSocket ( CocoaAsyncSocket ) 用于我的应用程序中的套接字通信。由于GCDAsyncSocket的异步性质,我的网络请求( submitMessage 下面)与接收数据时运行的回调 block ( socket:didReadData )解耦。

- (void)submitMessage:(NSDictionary *)messageObject onCompletion:(completionBlock)block {
    ...
    [_socket writeData:requestData withTimeout:self.timeout tag:0];
    [_socket readDataToLength:4 withTimeout:self.timeout tag:TAG_HEADER];
}

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    ...
    NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    if (self.completionBlock != nil)
        self.completionBlock(responseObject);
    }
}

这种方法对于一次性交换非常有效。但在某些情况下,我需要发布一个请求,然后使用收到的数据发布另一个请求。我无法让它正常工作。基本上,我需要这样的东西:

[self submitMessage:request1 onCompletion:^(NSDictionary *response1) {
    (...callback 1...)
    }];
    [self submitMessage:request2 onCompletion:^(NSDictionary *response2) {
        (...callback 2...)
    }];
}];

[self submitMessage:request1 onCompletion:^(NSDictionary *response1) {
    (...callback 1...)
}];
[self submitMessage:request2 onCompletion:^(NSDictionary *response2) {
    (...callback 2...)
}];

其中顺序严格为请求1 - 回调1 - 请求2 - 回调2。

那么问题是,如何阻止第一个请求回调后运行第二个请求?会GCD ( dispatch_sync ?) 是正确的选择吗?

编辑

我最终使用了类似于@tigloo建议的解决方案(因此接受他的答案),但使用 NSCondition而不是GCD (如果有人对细节感兴趣,我关注了 this great discussion )。我已经在运行多个线程(UI 在主线程中,高级套接字通信在另一个线程中,套接字操作在第三个线程中)。设置类属性并使用 NSCondition锁定GCDAsyncSocket委托(delegate)直到响应到达似乎是最简洁的方法。

最佳答案

我想你已经快到了。那又怎么样

[self submitMessage:request1 onCompletion:^(NSDictionary *response1) {
    // here, do something with response1 and create request2...
    // then you can make request2 directly at the end of the callback:
    [self submitMessage:request2 onCompletion:^(NSDictionary *response2) {
        // here, do something with response2...
    }];
}];

不需要 GCD 指令,不需要阻止执行(无论如何,这是一个不好的做法)。这能解决您的问题吗?

关于ios - 使用GCDAsyncSocket进行同步通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16143516/

相关文章:

ios - 如何在 iOS 后台运行 NSURLConnection

ios - 歧义使用 'subscript' - NSMutableDictionary

ios - Swift3 iOS - 如何在按下单元格之前从 TableView 中的所有 IndexPath 获取数据

objective-c - 从任意进程窃取 NSWindow (或 contentView)

IOS,Swift,无法访问 NSURLSession 中的主线程

Swift DispatchQoS.QoSClass 转换为 DispatchQueue.Attributes

ios - 使用 NIB 创建自定义 UIView

iphone - UITableViewCell 删除按钮没有出现

objective-c - 从另一个类方法更新 UI - Cocoa

当日期设置中的 24 小时时间在开和关之间切换时,iOS NSDate 比较的工作方式不同吗?