繁体   English   中英

AFMultipartBodyStream不支持scheduleInRunLoop机制的原因是什么?

[英]What is the reason that AFMultipartBodyStream does not support scheduleInRunLoop mechanism?

尽管AFMultipartBodyStream lib的AFNetworking是符合NSStreamDelegate协议的NSStream的子类,但无法像常规NSStream标准方式那样对其进行处理。 即, AFMultipartBodyStream无法通过流事件进行处理。 我查看了AFMultipartBodyStream的代码,发现它有意禁用了NSInputStream抽象类的scheduleInRunLoop方法:

- (void)scheduleInRunLoop:(__unused NSRunLoop *)aRunLoop
              forMode:(__unused NSString *)mode
{}

- (void)removeFromRunLoop:(__unused NSRunLoop *)aRunLoop
              forMode:(__unused NSString *)mode
{}

有什么具体原因吗? 是否有使其支持标准流事件机制的方法,以便可以使用stream:handleEvent:事件处理程序异步完成流数据处理?

在研究了AFMultipartBodyStream的实现之后,我注意到当前的实现方式无法支持常规流IO处理的异步方式。 然后,我增强了AFMultipartBodyStream的功能,以提供一个与内部多部分数据结构连接的流,因此,该AFMultipartBodyStream的所有者可以将多部分数据作为常规流处理,可以在运行循环中对其进行调度。 下面的代码段显示了主要思想:

-(NSInputStream *)inputStream {
    // If _inputStream has not been connected with HTTPBodyParts data, establish the connection
    if (!_inputStream) {
        NSParameterAssert([self.HTTPBodyParts count] != 0);
        CFReadStreamRef readStream;
        CFWriteStreamRef writeStream;
        CFIndex bufferSize = self.contentLength;
        CFStreamCreateBoundPair(NULL, &readStream, &writeStream, bufferSize);
        _inputStream = (__bridge_transfer NSInputStream *)readStream;
        _outputStream = (__bridge_transfer NSOutputStream *)writeStream;
        [_outputStream setDelegate:self];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            NSLog(@"\n====in async block of inputStream....====\n");

            [self->_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [self open];
            [self->_outputStream open];
            NSInteger totalBytesSent = self.contentLength;
            while (totalBytesSent > 0 && [self->_outputStream hasSpaceAvailable]) {
                uint8_t buffer[1024];
                NSInteger bytesRead = [self read:buffer maxLength:1024];
                totalBytesSent -= bytesRead;
                NSLog(@"\n====buffer read (%ld): [%s]====\n", (long)bytesRead, buffer);
                if (self.streamError || bytesRead < 0) {
                    break;
                }

                NSInteger bytesWritten = [self->_outputStream write:buffer maxLength:(NSUInteger)bytesRead];
                if (self->_outputStream.streamError || bytesWritten < 0) {
                    NSLog(@"\n====Socket write failed[%@]====\n", self->_outputStream.streamError);
                    break;
                }

                if (bytesRead == 0 && bytesWritten == 0) {
                    break;
                }
            }

            [self->_outputStream close];
            [self->_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        });
    }

    return _inputStream;
}




// Added
- (void)scheduleInRunLoop:(__unused NSRunLoop *)aRunLoop
                  forMode:(__unused NSString *)mode
{
    // Setup the input stream for body stream data consuming
    NSInputStream *inputStream = [self inputStream];
    NSParameterAssert(inputStream == self.inputStream);
    [inputStream setDelegate:self.delegate_];
    [inputStream scheduleInRunLoop:aRunLoop forMode:mode];
    [inputStream open];
}
// Added
- (void)removeFromRunLoop:(__unused NSRunLoop *)aRunLoop
                  forMode:(__unused NSString *)mode
{
    if (_inputStream) {
        [_inputStream setDelegate:[self delegate]];
        [_inputStream removeFromRunLoop:aRunLoop forMode:mode];
        [_inputStream close];
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM