[英]NSInputStream read: maxlength: returning way more bytes than 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.