簡體   English   中英

- [NSInputStream read:maxLength:]拋出一個異常,說長度太大,但事實並非如此

[英]-[NSInputStream read:maxLength:] throws an exception saying length is too big, but it isn't

我使用NSInputStream從文件中讀取數據。 如果maxLength大於49152,它將崩潰。

當它崩潰時 - 有時候,但不是每次都崩潰,它會給出這樣的信息:

***由於未捕獲的異常'NSInvalidArgumentException'終止應用程序,原因:'*** - [NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:]:荒謬長度:4294967295,最大大小:2147483648字節'

根據我的計算,524288仍然小於該最大值,並且可以適合返回值。 我錯過了什么?

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    switch (eventCode)
    {
        case NSStreamEventHasBytesAvailable:
        {
            NSInteger bufferSizeNumber = 524288;   //this one will crash.
//            NSInteger bufferSizeNumber = 491520;  // this one will work.

            uint8_t buf[bufferSizeNumber];
            unsigned int len = 0;

            len = [_stream read:buf maxLength:bufferSizeNumber];   //crashing at this line

            // more code ...

        }
        // more  code...
    }
}

編輯:(我認為這是該行為的關鍵部分)

如果我在后台線程中“啟動”,則bufferSizeNumber的行為如上所述。 但是如果我在主線程中“啟動”,則bufferSizeNumber在崩潰之前可以達到943713。

- (void)start
{
    _stream.delegate = self;
    [_stream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                       forMode:NSDefaultRunLoopMode];
    [_stream open];
    [[NSRunLoop currentRunLoop] run];
}

你的問題是所謂的“堆棧溢出”(你可能以前聽過這個)。

您的方法使用可變長度數組在堆棧上分配緩沖區:

uint8_t buf[bufferSizeNumber];

當緩沖區的大小太大以至於溢出當前堆棧的大小時,行為是不確定的。 未定義的行為可能會導致崩潰或只是按預期工作:只是您正在觀察的內容。

512kB是一個巨大的緩沖區,特別是在iOS上,后台線程的堆棧大小正是這樣。

你應該在堆上分配它:

NSInteger bufferSizeNumber = 524288;
NSMutableData *myBuffer = [NSMutableData dataWithLength:bufferSizeNumber];

uint8_t *buf = [myBuffer mutableBytes];
unsigned int len = 0;

len = [_stream read:buf maxLength:bufferSizeNumber];
// more code ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM