iOS:outputStream不会保持打开状态

时间:2013-05-30 19:26:51

标签: ios nsstream nsinputstream nsoutputstream

好的,我正在实现NSOutput和输入流。当它们被初始化时,流打开并连接到我在PC上运行的TCPServer,但是在初始化功能之外似乎关闭一次,或者流可能没有正确存储。我不太确定,所以非常感谢任何帮助

在我的.h文件中:

@interface AVCamViewController : UIViewController <UIImagePickerControllerDelegate,UINavigationControllerDelegate, NSStreamDelegate> {
    NSOutputStream *outputStream;
    NSInputStream *inputStream;
}

@property (retain) NSInputStream *inputStream;
@property (retain) NSOutputStream *outputStream;

在我的.m文件中:

@synthesize inputStream, outputStream;

    -(void)sendaResponse
    {
        NSString *response = [NSString stringWithFormat:@"Hello from Ipad Simulator"];
        NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
        [outputStream write:[data bytes] maxLength:[data length]];
        NSLog(@"%u", outputStream.streamStatus);
    }

    -(void)initNetworkCommunication
    {
        CFReadStreamRef readStream;
        CFWriteStreamRef writeStream;
        CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.9.100.122", 80, &readStream, &writeStream);

        NSInputStream *inputStream = (NSInputStream *) readStream;
        NSOutputStream *outputStream = (NSOutputStream *) writeStream;

        [inputStream setDelegate:self];
        [outputStream setDelegate:self];
        [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [inputStream open];
        [outputStream open];


        NSLog(@"%u and %u", inputStream.streamStatus, outputStream.streamStatus);
        NSString *response = [NSString stringWithFormat:@"Hello from Mikes Ipad Simulator"];
        NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
        [outputStream write:[data bytes] maxLength:[data length]];
        NSLog(@"%u", outputStream.streamStatus);
    }

    -(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
    {
        switch (eventCode) {
            case NSStreamEventOpenCompleted:
                NSLog(@"Stream Opened %u", outputStream.streamStatus);
                break;

            case NSStreamEventHasBytesAvailable:
                if(aStream == inputStream)
                {
                    uint8_t buffer [1024];
                    int len;

                    while ([inputStream hasBytesAvailable])
                    {
                        len = [inputStream read:buffer maxLength:sizeof(buffer)];
                        if(len>0)
                        {
                            NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

                            if(nil != output)
                            {
                                NSLog(@"Server said: %@", output);
                            }
                        }
                    }
                }
                break;

            case NSStreamEventErrorOccurred:
                NSLog(@"Can not connect to the host!");
                break;

            case NSStreamEventEndEncountered:
                if(aStream == inputStream)
                    NSLog(@"Ending input stream");
                if(aStream == outputStream)
                    NSLog(@"Ending output stream");

                [aStream close];
                [aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
                [aStream release];
                aStream = nil;
                break;

            default:
                break;
        }
    }

在initNetworkConnection中,模拟器连接到我的TCPServer并打开连接(streamstatus = 2)。收到消息“来自Ipad Simulator的Hello”。 但是后来我从按钮点击调用了“sendaResponse”方法,然后streamstatus = 0并且“outputstream”似乎没有被初始化。我只是没有正确保留变量吗?

1 个答案:

答案 0 :(得分:3)

我假设你正在使用ARC。 删除此代码:

{
NSOutputStream *outputStream;
NSInputStream *inputStream;
}

@synthesize inputStream, outputStream;

这让您在属性和实例变量之间感到困惑。拥有它的结果是你直接设置实例变量,并且你的流实例正被ARC释放。

相反,在您删除上述代码后,请使用self.inputStreamself.outputStream访问流。这将允许属性正常工作,并确保遵守您配置的“保留”规范。

您的原始代码也可能不是在尝试设置属性... 您的配置应该是:

    NSInputStream *inputStream = (NSInputStream *) readStream;
    NSOutputStream *outputStream = (NSOutputStream *) writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];

self.inputStream = inputStream;
self.outputStream = outputStream;

然后将属性更改为:

@property (strong) NSInputStream *inputStream;
@property (strong) NSOutputStream *outputStream;