因此,在更新部分代码未按预期运行后,我最近更新了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函数中。
答案 0 :(得分:0)
根据您的评论, reader?.readByte().hasValue
返回的数字很大 。 (我相信 hasValue
只是一个错字,而它的 hashValue
。)< / p>
这是hashValue
的可能行为。
您是否将hashValue
用作UInt8
到Int
的转换工具?
错了。属性hashValue
已实现(并且应该实现)以返回满足某个公理的某些Int
值:
where a == b, a.hashValue == b.hashValue
在较早版本的Swift中,UInt8.hashValue
可能返回了Int
类型的相同值,但是您不应该依赖未记录的实现细节。实施上的微小变化会导致不同的结果。
事实上,Swift 4.2彻底改变了hashValue
的实现。
您可能需要使用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
通常,您最好不要在项目中包含此类错误的技巧。