Swift 4,读取字节数据

时间:2018-09-19 05:37:06

标签: objective-c swift4 inputstream outputstream

因此,在更新部分代码未按预期运行后,我最近更新了IMAC和Xcode。这是我最初查看邮件的地方。

func checkForMessages() {
    while true {
        if inputBuffer.length < 4 {
            return
        }
        var msgLength = (inputBuffer.bytes).load(as: UInt32.self)
        msgLength = UInt32(bigEndian: msgLength)
        print("msgLength = \(msgLength)")
        print("inputBuffer Length = \(inputBuffer.length)")
        print("inputBuffer = \(inputBuffer)")
        if inputBuffer.length < msgLength {
            return
        }
        //print("data = \(inputBuffer.subdata(with: NSRange(location: 4, length: Int(msgLength))))")
        if inputBuffer.length < msgLength + 4 {
            return
        }
        let message: Data? = inputBuffer.subdata(with: NSRange(location: 4, length: Int(msgLength)))
        processMessage(message!)
        let amtRemaining: Int = inputBuffer.length - Int(msgLength) - 4
        if amtRemaining == 0 {
            inputBuffer = NSMutableData()
        }
        else {
            print("Creating input buffer of length \(amtRemaining)")
            inputBuffer = NSMutableData(bytes: inputBuffer.bytes + 4 + Int(msgLength), length: amtRemaining)
        }
    }
}

然后是过程消息功能

func processMessage(_ data: Data) {

    let reader = MessageReader(data: data)
    print("this is the message data\(data)")
    let msgType  = reader?.readByte().hashValue
}

,然后是实际的MessageReader,它位于Objective C中,因为前一段时间我将其从互联网上撤了下来。从那时起,它一直对我有效。直到现在。

#import "MessageReader.h"

@implementation MessageReader

- (id)initWithData:(NSData *)data {
   if ((self = [super init])) {
      _data = data;
      _offset = 0;
}
return self;
}

- (unsigned char)readByte {
    unsigned char retval = *((unsigned char *) (_data.bytes + _offset));
    _offset += sizeof(unsigned char);
    return retval;
}

- (int)readInt {
    int retval = *((unsigned int *) (_data.bytes + _offset));
   retval = ntohl(retval);
   _offset += sizeof(unsigned int);
   return retval;
}

- (NSString *)readString {
   int strLen = [self readInt];
   NSString *retval = [NSString stringWithCString:_data.bytes + _offset encoding:NSUTF8StringEncoding];
   _offset += strLen;
   return retval;
}

- (void)dealloc {
}

@end

现在的问题是,与其返回诸如“ 1”或“ 2”,“ 30”之类的数字,不如返回诸如1836718193728之类的巨大数字。我相信问题出在messageReader,readByte函数中。

1 个答案:

答案 0 :(得分:0)

根据您的评论, reader?.readByte().hasValue返回的数字很大 。 (我相信 hasValue 只是一个错字,而它的 hashValue 。)< / p>

这是hashValue的可能行为。

您是否将hashValue用作UInt8Int的转换工具?

错了。属性hashValue已实现(并且应该实现)以返回满足某个公理的某些Int值:

where a == b, a.hashValue == b.hashValue

在较早版本的Swift中,UInt8.hashValue可能返回了Int类型的相同值,但是您不应该依赖未记录的实现细节。实施上的微小变化会导致不同的结果。

事实上,Swift 4.2彻底改变了hashValue的实现。

SE-0206 Hashable Enhancements

您可能需要使用hashValue修复项目的所有部分。 通常,您使用Int.init(_:)UInt8转换为Int

let msgType中所示的“可选链接”之类的环境中,您可能需要编写如下内容。

    let msgType = (reader?.getByte()).map{Int($0)}

如果您错误地使用hashValue的零件很多,最好写一个扩展名:

extension UInt8 {
    var integerValue: Int {
        return Int(self)
    }
}

    let msgType = reader?.getByte().integerValue

通常,您最好不要在项目中包含此类错误的技巧。