NSInputStream останавливается, иногда выдает EXC_BAD_ACCESS

(ОБНОВЛЕНО) это проблема в двух словах: в iOS я хочу прочитать большой файл, выполнить некоторую обработку на нем (в данном конкретном случае кодировать как Base64 string () и сохранить во временном файле на устройстве. Я настроил NSInputStream для читать из файла, затем в

(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode

Я делаю большую часть работы. Почему-то иногда я вижу, что NSInputStream просто перестает работать. Я знаю, потому что у меня есть линия

NSLog(@"stream %@ got event %x", stream, (unsigned)eventCode);

в начале(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode а иногда я просто вижу выход

stream <__NSCFInputStream: 0x1f020b00> got event 2

(что соответствует событию NSStreamEventHasBytesAvailable), а затем ничего после этого. Не событие 10, которое соответствует NSStreamEventEndEncountered, не событие ошибки, ничего! А также иногда я даже получаю исключение EXC_BAD_ACCESS, которое в настоящий момент не знаю, как отлаживать. Любая помощь будет оценена.

Вот реализация. Все начинается, когда я нажимаю кнопку «отправить», которая вызывает:

- (IBAction)submit:(id)sender {     
    [p_spinner startAnimating];    
    [self performSelector: @selector(sendData)
           withObject: nil
           afterDelay: 0];   
}

Вот sendData:

-(void)sendData{
    ...
    _tempFilePath = ... ;
    [[NSFileManager defaultManager] createFileAtPath:_tempFilePath contents:nil attributes:nil];
    [self setUpStreamsForInputFile: [self.p_mediaURL path] outputFile:_tempFilePath];
    [p_spinner stopAnimating];
    //Pop back to previous VC
    [self.navigationController popViewControllerAnimated:NO] ;
}

Вот setUpStreamsForInputFile, вызванный выше:

- (void)setUpStreamsForInputFile:(NSString *)inpath outputFile:(NSString *)outpath  {
    self.p_iStream = [[NSInputStream alloc] initWithFileAtPath:inpath];
    [p_iStream setDelegate:self];
    [p_iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                           forMode:NSDefaultRunLoopMode];
    [p_iStream open];   
}

Наконец, именно здесь происходит большая часть логики:

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {

    NSLog(@"stream %@ got event %x", stream, (unsigned)eventCode);

    switch(eventCode) {
        case NSStreamEventHasBytesAvailable:
        {
            if (stream == self.p_iStream){
                if(!_tempMutableData) {
                    _tempMutableData = [NSMutableData data];
                }
                if ([_streamdata length]==0){ //we want to write to the buffer only when it has been emptied by the output stream
                    unsigned int buffer_len = 24000;//read in chunks of 24000
                    uint8_t buf[buffer_len];
                    unsigned int len = 0;
                    len = [p_iStream read:buf maxLength:buffer_len];
                    if(len) {
                        [_tempMutableData appendBytes:(const void *)buf length:len];
                        NSString* base64encData = [Base64 encodeBase64WithData:_tempMutableData];
                        _streamdata = [base64encData dataUsingEncoding:NSUTF8StringEncoding];  //encode the data as Base64 string
                        [_tempFileHandle writeData:_streamdata];//write the data
                        [_tempFileHandle seekToEndOfFile];// and move to the end
                        _tempMutableData = [NSMutableData data]; //reset mutable data buffer 
                        _streamdata = [[NSData alloc] init]; //release the data buffer
                    } 
                }
            }
            break;
        case NSStreamEventEndEncountered:
        {
            [stream close];
            [stream removeFromRunLoop:[NSRunLoop currentRunLoop]
                              forMode:NSDefaultRunLoopMode];
            stream = nil;
            //do some more stuff here...
            ...
            break;
        }
        case NSStreamEventHasSpaceAvailable:
        case NSStreamEventOpenCompleted:
        case NSStreamEventNone:
        {
           ...
        }
        }
        case NSStreamEventErrorOccurred:{
            ...
        }
    }
}

Примечание: когда я впервые опубликовал это, у меня сложилось неверное впечатление, что проблема связана с использованием GCD. Согласно ответу Роба ниже, я удалил код GCD, и проблема не устранена.

Ответы на вопрос(2)

Ваш ответ на вопрос