我在iOS上做了一段时间的客户端 - 服务器通信,但我遇到了一个问题,我有些麻烦需要理解。
我写了两个基本功能:一个用于向服务器发送数据,另一个用于从服务器接收数据。每个都有一个名为timeout的参数,它允许当前线程休眠并每0.25秒唤醒一次,直到达到超时:
-(ReturnCode) send : (NSData*)data :(int)timeOut
{
if(![self isConnectionOpened]) return KO;
float timer = 0;
while(![_outputStream hasSpaceAvailable])
{
[NSThread sleepForTimeInterval:0.25];
timer+=0.25;
if(timer == timeOut) break;
}
int ret = 0;
if([_outputStream hasSpaceAvailable]){
int lg = [data length];
ret = [_outputStream write:[data bytes] maxLength:lg];
if(ret == -1) return KO;
else return OK;
}
return TIMEOUT;
}
- (ReturnCode) receive : (NSData**)data : (int)timeOut : (int)maxLength
{
uint8_t buffer[maxLength];
int len;
NSMutableData* dataReceived = [[NSMutableData alloc] init];
if(! [self isConnectionOpened]) return KO;
float timer = 0;
while(![_inputStream hasBytesAvailable])
{
[NSThread sleepForTimeInterval:0.25];
timer+=0.25;
if(timer == timeOut) break;
}
if(![_inputStream hasBytesAvailable]) return TIMEOUT;
while ([_inputStream hasBytesAvailable]) {
len = [_inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
[dataReceived appendBytes:buffer length:len];
*data = dataReceived;
return OK;
}
}
return KO;
}
使用iPhone 4 + iOS6,一切都很顺利。但是在iOS7下,由于某些模糊原因,输入流和输出流过早关闭(引发了NSStreamEventErrorOccurred)。事实是,如果我在从服务器接收数据之前放置一个断点并使代码运行,它就可以正常工作并且读/写流不会错误地关闭。
所以我认为存在同步问题,但我不明白为什么......如果有人有想法,请帮忙......
答案 0 :(得分:1)
我找到了问题的来源。
实际上,要非常小心预定输入流和输出流的位置。实际上,我被告知必须在主线程上执行Apple对象,所以我按照这种方式安排它们:
dispatch_async(dispatch_get_main_queue(), ^ {
[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_inputStream open];
[_outputStream open];
});
但实际上,最好在当前线程的当前循环上安排它们,而不是在主线程上调度schedule动作:
[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_inputStream open];
[_outputStream open];