首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSStream关闭得太快

NSStream关闭得太快
EN

Stack Overflow用户
提问于 2013-11-23 17:10:13
回答 1查看 309关注 0票数 0

我已经用iOS做了一段时间的客户机-服务器通信,但是我在这里面临一个问题,我有一些问题需要理解。

我编写了两个基本功能:一个向服务器发送数据,另一个从服务器接收数据。每个线程都有一个名为timeout的参数,该参数允许使当前线程休眠并每0.25s唤醒一次,直到达到超时为止:

代码语言:javascript
复制
-(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升高)。事实是,如果我在从服务器接收数据之前放置一个断点并使代码运行,它工作正常,读取/写入流不会错误地关闭。

所以我认为有一个同步问题,但我不明白为什么.如果有人有想法,请帮忙.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-29 19:04:37

我发现了我的问题来自何方。

实际上,在排定的输入流和输出流的位置上要非常小心。事实上,有人告诉我,苹果对象必须在主线程上执行,所以我就这样安排了它们:

代码语言:javascript
复制
dispatch_async(dispatch_get_main_queue(), ^ {
     [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
     [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

     [_inputStream open];
     [_outputStream open];
});

但实际上,最好是将它们从当前线程调度到当前循环上,而不是在主线程上分配调度操作:

代码语言:javascript
复制
     [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
     [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

     [_inputStream open];
     [_outputStream open];
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20165314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档