0

私はObjective-cを学ぼうとしています。私は次のことを行ってバイナリファイルを解析しようとしています(簡略化):

@interface DatFile : NSObject {
    NSData* _data;
}

-(id)initWithFilePath:(NSString *)filePath;

-(void) readFile;

-(void) auxiliaryMethod;



@implementation DatFile

- (id) initWithFilePath:(NSString *)filePath {
    if ( self = [super init] ) {
        _data = [NSData dataWithContentsOfFile:filePath];
    }
    return self;
}

-(void) readFile {
    int header;
    [_data getBytes: &header range: NSMakeRange(0, 4)];    
    NSLog(@"header: %u", header);

    short key;
    [_data getBytes: &key range: NSMakeRange(4, 2)];
    NSLog(@"key: %u", key);

    short value;
    [_data getBytes: &value range: NSMakeRange(6, 1)];
    NSLog(@"value: %u", value);

    [self auxiliaryMethod];
}

-(void) auxiliaryMethod {
    short value;
    [_data getBytes: &value range: NSMakeRange(6, 1)];
    NSLog(@"value: %u", value);
}

私の問題は、auxiliaryMethod内のコードが、 readFileメソッドによって計算されたのと同じ値を計算しないことです。_dataオブジェクトは同じなので、メソッドが異なる値を計算するのはなぜですか?そして、ご覧のとおり、auxiliaryMethod内のロジックは他のロジックの単なるコピーです...

他の言語(java)では、コードモードを読み取り可能/保守可能にするために、通常、いくつかのロジックを小さなメソッドに分離します。これが私がObjCでそれを模倣しようとしている理由です。

もちろん、それはおそらく何かが欠けていますが、数時間後、私はあきらめました。どこに間違いがあるのか​​わかりません。おそらく、プロジェクトを消去して再開する必要があります...

TIA、

ボブ

4

2 に答える 2

3

%u32ビットの符号なし値を出力するためのものです。ショートは16ビットです。したがって、解析された値といくつかのスタックガベージを出力しています。

試してみてください%hu; 短い値を出力するようにh変更します。%u


それが機能しない場合:

  • データオブジェクトが2つのメソッド間で同じであることを確認してください(どのようにできないかはわかりません...しかし...)
  • 印刷された実際の値を表示する
  • デコードする前に明示的に0に初期化されるunsignedlongにデコードします

この種のバグでは、自分が思っている入力を処理していないか、この種のコードのデータ型と暗黙の変換に関連するC-ismを処理していることがほぼ確実です。

_dataつまり、一貫性があると仮定すると、機能していると思われるコードが実際には機能しておらず、偶然にしか機能していないことを示しています。

于 2012-07-02T19:57:55.900 に答える
2

問題は、サイズ1からの範囲を渡しているgetBytes:range:が、shortのサイズは2バイトであるということです。したがって、のバイトのgetBytes:range:1つだけを設定し、もう1つにはランダムなガベージが含まれています。value

本当にデータから1バイトだけを取得したい場合は、タイプをに変更しvalueint8_tください。2バイトを取得する場合は、の2番目の引数として2を渡しますNSMakeRange(また、タイプをvalueに変更することをお勧めしint16_tます)。

于 2012-07-02T21:32:12.213 に答える