【问题标题】:iOS: outputStream does not stay openiOS:outputStream 不保持打开状态
【发布时间】:2013-05-30 19:26:51
【问题描述】:

好的,我正在实现一个 NSOutput 和 Input Streams。当它们被初始化时,流打开并连接到我在我的 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 模拟器的你好”。 但是后来我通过单击按钮调用了“sendaResponse”方法,然后streamstatus = 0并且“outputstream”似乎没有被初始化。我只是没有正确保留变量吗?

【问题讨论】:

    标签: ios nsstream nsinputstream nsoutputstream


    【解决方案1】:

    我假设您使用的是 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;
    

    【讨论】:

    • 谢谢,非常感谢您的快速响应!
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    相关资源
    最近更新 更多