NSData指针与引用

时间:2014-03-13 19:55:55

标签: objective-c pointers nsdata

我正在处理garmin GDL90协议,该协议将各种类型的二进制消息发送到我的IOS设备。我正在尝试处理所有这些消息,但一直遇到问题。具体来说,消息是字节打包的,所以如果你看到

的出现

0x7d 0x5e0x7d 0x5d您必须将其转换为0x7d or 0x7e

我已经设置了我的代码,以便检测我正在解析的消息类型,然后调用一个函数:

- (void) parseMessage:(NSMutableData *)message

进行数据解析。我的个人消息解析函数调用父函数[super parseMessage:message];,它处理公共元素的解析以及处理我的字节填充。这些函数调用中的每一个都需要一个NSData *,所以在我的超级函数中进行的修改不应该返回相同的数据吗?

  • 我的顶级类获得一个解析消息调用,NSMutableData指针的地址是: 0x170048f10
  • 一旦我进入父母的parseData调用,我的地址仍然是 0x170048f10
  • 在对数据进行修改后,我现在指向内存地址 0x17805e840
  • 然而,当我从此功能返回时,我又用错误的数据再次指向 0x170048f10

我应该使用传递参考或其他什么?有什么建议?

我的功能有两种变体 - unstuff1 会抛出错误而 unstuff2 无法正常工作。

- (NSMutableData *)unstuff1:(NSMutableData *)mutableData {
    int dataLength = [mutableData length];
    char *bytes = [mutableData bytes];

    // Scan bytes ignoring 1st and last byte because they will be 7e's
    for (int i = dataLength - 1; i > 0; i--) {
        bytes[i + 1] ^= 0x20;

        if (i + 1 == dataLength) {
            NSLog(@"Terminal character padding detected on character %d with length %d", i, dataLength);
        } else {
            /* Replace 2 bytes with a single byte should remove the flag when you do this */
            [mutableData replaceBytesInRange:NSMakeRange(i, 2) withBytes:&bytes[i + 1] length:1];

            dataLength--;
        }

    }
    return mutableData;
}

- (NSMutableData *)unstuff2:(NSMutableData *)data {

    NSMutableData *mutableData = [[NSMutableData alloc] initWithData:data];
    int dataLength = [mutableData length];
    char *bytes = [mutableData bytes];

    // Scan bytes ignoring 1st and last byte because they will be 7e's
    for (int i = dataLength - 1; i > 0; i--) {
        bytes[i + 1] ^= 0x20;

        if (i + 1 == dataLength) {
            NSLog(@"Terminal character padding detected on character %d with length %d", i, dataLength);
        } else {
            /* Replace 2 bytes with a single byte should remove the flag when you do this */
            [mutableData replaceBytesInRange:NSMakeRange(i, 2) withBytes:&bytes[i + 1] length:1];

            dataLength--;
        }

    }
    return mutableData;
}

unstuff2 中,显然我正在创建一个新的MutableData,所以我猜这会占用内存地址的变化(这就是我使用的函数,这给了我指定的错误)。

unstuff1 会抛出以下异常:

  

- [_ NSInlineData replaceBytesInRange:withBytes:length:]:无法识别的选择器发送到实例0x178250d40

     

由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:' - [_ NSInlineData replaceBytesInRange:withBytes:length:]:无法识别的选择器发送到实例

2 个答案:

答案 0 :(得分:1)

与C ++和C#等语言不同(仅举两个例子),Objective C没有“按引用传递”的概念。但是,将指针的副本传递给NSMutableData在功能上等同于通过引用传递对象。也就是说,如果您将一个NSMutableData(或NSMutableAnything)传递给一个函数并且该函数修改它,那么调用函数将看到它传入的对象中反映的更改。

答案 1 :(得分:1)

好的,好像我追查了这个问题。我意识到编译器正在发出警告:

不兼容的指针类型使用“NSData *”类型的表达式初始化“NSMutableData *”

事实证明我有一些代码

NSMutableData *message = [data subdataWithRange:NSMakeRange(5, len - 5)];

我需要将其转换为:

NSMutableData *message = [NSMutableData dataWithData:[data subdataWithRange:NSMakeRange(5, len - 5)]];

然后事情一切顺利。故事的道德(阅读你的警告!!!!)