处理指向包含 Swift 中数组的结构的指针

Dealing with pointers to structs containing arrays in Swift

我正在尝试在 Swift 中编写一个 Mac 应用程序,它通过 http://rsms.me/peertalk/ 提供的名为 PeerTalk 的库与 iOS 设备通信,所以我一直试图重写 Swift 中的 PeerTalk 示例项目。我的 Swift 重写可以正确连接并从 iOS 设备接收消息,但无法在不崩溃的情况下读取消息。

struct PTExampleTextFrame {
    let length: UInt32
    let utf8text: [UInt8]
}

func ioFrameChannel(channel: PTChannel?, didReceiveFrameOfType type: UInt32, tag: UInt32, payload: PTData?) {
    if (type == PTExampleFrameTypeDeviceInfo) {
        let deviceInfo: NSDictionary? = NSDictionary(contentsOfDispatchData: payload!.dispatchData)
        self.presentMessage(NSString(format: "Connected to %@", deviceInfo!.description), isStatus:true)
    } else if (type == PTExampleFrameTypeTextMessage) {

        let textFramePointer = UnsafeMutablePointer<PTExampleTextFrame>(payload!.data)
        let textFrameOptional: PTExampleTextFrame? = textFramePointer.memory
        let textFrame: PTExampleTextFrame

        if textFrameOptional != nil {
            textFrame = textFrameOptional!
            println(ntohl(textFrame.length))
            println(textFrame.utf8text)
        } else {
            println("Recieved bad packet")
        }

    } else if (type == PTExampleFrameTypePong) {
        self.pongWithTag(tag, error:nil)
    }

}

下面的结构和块是我遇到问题的唯一部分。

    let textFramePointer = UnsafeMutablePointer<PTExampleTextFrame>(payload!.data)
    let textFrameOptional: PTExampleTextFrame? = textFramePointer.memory
    let textFrame: PTExampleTextFrame

    if textFrameOptional != nil {
        textFrame = textFrameOptional!
        println(ntohl(textFrame.length))
        println(textFrame.utf8text)
    } else {
        println("Recieved bad packet")
    }

当我的应用程序收到一条消息时,ioFrameChannel 函数被成功调用并打印崩溃前发送的消息的正确长度

Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)

行打印 textFrame.utf8text 运行时。

将结构替换为不包含数组的结构成功地按预期打印了消息第一个字符的 UTF-8 表示形式。

struct PTExampleTextFrame {
    let length: UInt32
    let utf8text: UInt8
}

上面的工作 Objective C 如下面的示例项目所写

//PTExampleProtocol.h
typedef struct _PTExampleTextFrame {
  uint32_t length;
  uint8_t utf8text[0];
} PTExampleTextFrame;

//PTAppDelegate.m
- (void)ioFrameChannel:(PTChannel*)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData*)payload {
  //NSLog(@"received %@, %u, %u, %@", channel, type, tag, payload);
  if (type == PTExampleFrameTypeDeviceInfo) {
    NSDictionary *deviceInfo = [NSDictionary dictionaryWithContentsOfDispatchData:payload.dispatchData];
    [self presentMessage:[NSString stringWithFormat:@"Connected to %@", deviceInfo.description] isStatus:YES];
  } else if (type == PTExampleFrameTypeTextMessage) {
    PTExampleTextFrame *textFrame = (PTExampleTextFrame*)payload.data;
    textFrame->length = ntohl(textFrame->length);
    NSString *message = [[NSString alloc] initWithBytes:textFrame->utf8text length:textFrame->length encoding:NSUTF8StringEncoding];
    [self presentMessage:[NSString stringWithFormat:@"[%@]: %@", channel.userInfo, message] isStatus:NO];
  } else if (type == PTExampleFrameTypePong) {
    [self pongWithTag:tag error:nil];
  }
}

我预计崩溃与 Swift 不知道阵列何时停止有关。我如何才能在 Swift 中阅读整条消息而不让我的应用程序崩溃?

随着我对 Swift 的更多了解,似乎将具有 0 长度数组的 ObjC 结构作为零元组导入到 swift 中。定长数组作为元组导入,因为 Swift 中不存在定长数组。我假设指向零元组的指针可以用于此目的;但是,我没有测试,因为我没有使用这个协议,而是重写了 iOS 应用程序并完全改变了协议,甚至不需要这个奇怪的结构。