Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 缓冲NSOutputStream用作NSInputStream?_Iphone_Cocoa_Nsstream - Fatal编程技术网

Iphone 缓冲NSOutputStream用作NSInputStream?

Iphone 缓冲NSOutputStream用作NSInputStream?,iphone,cocoa,nsstream,Iphone,Cocoa,Nsstream,我有一个consumer类,它将NSInputStream作为参数进行异步处理,我希望推送来自生产者类的数据,生产者类要求它提供一个NSOutputStream作为其输出源。现在,我如何设置一个缓冲(或透明)流作为生产者的输出流,同时作为我的消费者类的NSInputStream 我已经研究了NSOutputStream+outputStreamToMemory和+outputStreamToBuffer:capacity:但还没有真正弄清楚如何将其用作NSInputSource的输入 我有一个想

我有一个consumer类,它将NSInputStream作为参数进行异步处理,我希望推送来自生产者类的数据,生产者类要求它提供一个NSOutputStream作为其输出源。现在,我如何设置一个缓冲(或透明)流作为生产者的输出流,同时作为我的消费者类的NSInputStream

我已经研究了NSOutputStream+outputStreamToMemory和+outputStreamToBuffer:capacity:但还没有真正弄清楚如何将其用作NSInputSource的输入

我有一个想法,就是建立一个中间人类来保存实际的缓冲区,然后创建两个子类(每个NSInput/OutputStream一个子类)来保存对该缓冲类的引用,并让这些子类将大多数调用委托给该类,例如输出子类方法hasSpaceAvailable,write:maxLength:,以及对于输入,hasbytes可用,读取:maxLength:等


任何关于如何处理这种情况的提示都将不胜感激。谢谢

实现这一点的一种方法是使用apple开发者网站上的示例代码。

正如PostController.m代码中所示,这是如何做到的

@interface NSStream (BoundPairAdditions)
+ (void)createBoundInputStream:(NSInputStream **)inputStreamPtr outputStream:(NSOutputStream **)outputStreamPtr bufferSize:(NSUInteger)bufferSize;
@end

@implementation NSStream (BoundPairAdditions)

+ (void)createBoundInputStream:(NSInputStream **)inputStreamPtr outputStream:(NSOutputStream **)outputStreamPtr bufferSize:(NSUInteger)bufferSize
{
    CFReadStreamRef     readStream;
    CFWriteStreamRef    writeStream;

    assert( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) );

    readStream = NULL;
    writeStream = NULL;

    CFStreamCreateBoundPair(
        NULL, 
        ((inputStreamPtr  != nil) ? &readStream : NULL),
        ((outputStreamPtr != nil) ? &writeStream : NULL), 
        (CFIndex) bufferSize);

    if (inputStreamPtr != NULL) {
        *inputStreamPtr  = [NSMakeCollectable(readStream) autorelease];
    }
    if (outputStreamPtr != NULL) {
        *outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
    }
}
@end

基本上,你将两个流的结尾加上一个缓冲区。

你可能想考虑子类NStPixSt流,并在新的类中包装源流,缓冲和/或修改它们经过的字节。

我发现在绑定套接字方法上这样做的主要原因是支持查找。基于文件的NSInputStreams使用流属性在文件中进行搜索,如果不进行子类化,我无法轻松地安排这项工作

这种方法的一个问题是,似乎免费桥接对您的子类不起作用-但是有一篇非常好的文章,如果您需要模板子类,它还将为您提供一个模板子类:

我得到了一个使用这两种方法的缓冲解决方案-尽管子类方法的另一个问题是您需要注意将事件适当地发送给侦听器-例如,当您的源流向您发送EOF事件时,在消费者清空缓冲区之前,您不会将其传递给消费者,因此在这方面会有一些混乱

此外,您可能需要确保客户机读取主运行循环(我使用grand central dispatch获得了它),因为您在子类(源流)中所做的任何观察都会与使用者发生冲突。尽管您似乎能够选择任何运行循环来观察流,但只有主循环可以工作


因此,总的来说,我会说使用成对流,除非您需要支持查找-或者特别反对成对流方法。

这里有一个已经实现的类,它可以完全满足您的需要


从iOS 8开始,任何仍在使用Objective C的用户都可以使用以下标准方法:


这是一个很好的问题,我也在努力寻找答案!到目前为止,我想到的是使用文件作为中间人(这似乎不是很有效)。希望有人能找到更好的解决方案我在苹果开发者论坛上得到了一些提示,这些提示让我找到了CFStreamCreateBoundPair。SimpleURLConnections示例项目中有一些示例代码。你也可以退房。在那之后,我没有再深入研究它了。接收到的数据的handleEvent方法是在调用该方法时发生的(在同一个方法堆栈中),还是在另一个事件中触发的?你的意思是handleEvent方法是否与CreateBundInputStream在同一个调用堆栈中?IIRC,不。不,我是说inputStream的handleEvent方法是否与outputStream上调用的write方法位于同一个调用堆栈上?还是会被安排为新的活动?它们是独立的活动。一个用于生产者,一个用于消费者。我使用此方法创建了一对流。当NSOutputStream获取推送到其中的数据时,它会获取所有handleEvent委托回调,而我的NSInputStream上没有任何内容(没有委托回调)。有什么想法吗?
// initialize
self.bufferWriter = [[BufferOutputStreamToInputStream alloc] init];
[self.bufferWriter openOutputStream];

// later you want to set the delegate of the inputStream and shedule it in runloop
// remember, you are responsible for the inputStream, the outputStream is taken care off;)
self.bufferWriter.inputStream.delegate = self;
[self.bufferWriter.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.bufferWriter.inputStream open]

// fill with data when desired on some event      
[self.bufferWriter addDataToBuffer:someData];