为什么我从NSData读取字节时会得到不同的值,具体取决于我获取字节的顺序?

Sep*_*tih 3 cocoa objective-c nsdata

好吧,这更像是"到底是怎么回事?" 而不是一个实际问题.但鉴于我对C的相对缺乏经验,它可能会导致更大的问题.

基本上,我正在解析wav文件的标题并获取值.在我的头文件中,我定义了类变量:

short channels;
int sampleRate;
int bytesPerSecond;
short bytesPerSample;
short bitsPerSample;
unsigned int size;  
Run Code Online (Sandbox Code Playgroud)

并且类中用于获取这些值的函数如下:

NSData * fileData = [[NSData alloc] initWithContentsOfFile:filePath];
[fileData getBytes:&channels range:CHANNELS_R];
[fileData getBytes:&sampleRate range:SAMPLES_R];
[fileData getBytes:&bytesPerSecond range:BYTES_PER_SEC_R];
[fileData getBytes:&bytesPerSample range:BYTES_PER_SAMPLE_R];
[fileData getBytes:&bitsPerSample range:BITS_PER_SAMPLE_R];
[fileData getBytes:&size range:LENGTH_R];
Run Code Online (Sandbox Code Playgroud)

范围先前定义:

const NSRange CHANNELS_R = {22,23};
const NSRange SAMPLES_R = {24,27};
const NSRange BYTES_PER_SEC_R = {28,31};
const NSRange BYTES_PER_SAMPLE_R = {32,33};
const NSRange BITS_PER_SAMPLE_R = {34,35};
const NSRange LENGTH_R = {40,43};
Run Code Online (Sandbox Code Playgroud)

这工作正常,我得到所有的值,但是,如果我按顺序移动其中一行,或者在标题中的一个变量定义,它们会得到一个完全不同的值.例如,我正在进行的测试wav的采样率为8000.使用上面的代码我得到了正确的值.但是如果我移动指定它的值超过通道线的值,我得到524288000.太棒了.基本上,如果给出变量的顺序,它们的值与它们的定义顺序不对应,那就会混淆它.范围似乎对此行为没有任何影响.

任何人都知道这里发生了什么?

ken*_*ytm 6

const NSRange CHANNELS_R = {22,23};
const NSRange SAMPLES_R = {24,27};
const NSRange BYTES_PER_SEC_R = {28,31};
const NSRange BYTES_PER_SAMPLE_R = {32,33};
const NSRange BITS_PER_SAMPLE_R = {34,35};
const NSRange LENGTH_R = {40,43};
Run Code Online (Sandbox Code Playgroud)

不,NSRange不是这样的.定义NSRange

typedef struct _NSRange {
   NSUInteger location;
   NSUInteger length;
} NSRange;
Run Code Online (Sandbox Code Playgroud)

这意味着第二个成员是长度,而不是结束位置.当然你不想读取23个字节short(它溢出缓冲区并覆盖其他变量并导致你得到的现象).将它们更改为

const NSRange CHANNELS_R = {22,2};
const NSRange SAMPLES_R = {24,4};
const NSRange BYTES_PER_SEC_R = {28,4};
const NSRange BYTES_PER_SAMPLE_R = {32,2};
const NSRange BITS_PER_SAMPLE_R = {34,2};
const NSRange LENGTH_R = {40,4};
Run Code Online (Sandbox Code Playgroud)

然后再试一次.