【问题标题】:EXC_BAD_ACCESS when converting Objective-C code to Swift将 Objective-C 代码转换为 Swift 时的 EXC_BAD_ACCESS
【发布时间】:2016-01-20 07:42:51
【问题描述】:

我尝试在我的项目中使用 Objective-C 框架,但在将 Objective-C 代码转换为 Swift 时遇到了一些问题。

其中一个 API:

- (void)ioFrameChannel:(PTChannel*)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData*)payload

payload.data 是这样的结构:

typedef struct _PTExampleTextFrame {
  uint32_t length;
  uint8_t utftext[0];
} PTExampleTextFrame;

我想得到PTExampleTextFrame.utftext,这是从框架发送的消息

所以,我创建了一个本地的struct

struct CPTExampleTextFrame {
    var length: UInt32
    var utf8text: UnsafePointer<UInt8>
}

然后这样写:

var textFrame = UnsafePointer<CPTExampleTextFrame>(payload.data).memory
textFrame.length = CFSwapInt32(textFrame.length)
print(textFrame.length) // textFrame.length is correct!
let message = NSString(bytes: textFrame.utf8text, length: Int(textFrame.length), encoding: NSUTF8StringEncoding) // error
print(message)

但我得到一个错误:EXC_BAD_ACCESS(code=1,address=0x31)

谁能告诉我是什么问题?

我也给你这个框架的例子,它是在 Objective-C 中的:

- (void)ioFrameChannel:(PTChannel*)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData*)payload {
  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 appendOutputMessage:[NSString stringWithFormat:@"[%@]: %@", channel.userInfo, message]];
  } else if (type == PTExampleFrameTypePing && peerChannel_) {
    [peerChannel_ sendFrameOfType:PTExampleFrameTypePong tag:tag withPayload:nil callback:nil];
  }
}

【问题讨论】:

    标签: ios objective-c swift


    【解决方案1】:

    由于 Objective-C 是 C 的超集,我强烈建议您将与 C 接口的代码保留为 Objective-C 代码。直接连接 C 和 Swift 绝对是一件痛苦的事情。

    而且一个 char 数组和一个不安全的指向 char 的可变指针显然是不兼容的。

    【讨论】:

    • 感谢您的建议!最后,我使用了一种 Objective-C 方法来构建我需要的消息,而这只需要我一分钟......所以,我认为,在某些情况下,Swift 并不总是 Swift 项目中的最佳选择。
    【解决方案2】:

    你不需要创建本地结构,它的内存布局与 c 类型不兼容。

    澄清后:

    let x: PTExampleTextFrame = UnsafeMutablePointer&lt;PTExampleTextFrame&gt;(payload.data).memory

    然后随意使用 x

    【讨论】:

    • 我之前尝试过,但出现错误Cannot convert value of type 'UnsafeMutablePointer&lt;Void&gt;' (aka 'UnsafeMutablePointer&lt;()&gt;') to specified type 'PTExampleTextFrame' (aka '_PTExampleTextFrame')。之后我使用本地结构
    • payload.data 定义是怎样的?
    • 在这种情况下更新了我的答案
    • 当我按下 cmd+r 时,我得到一个错误'Command failed due to signal: Segmentation fault: 11',这是什么意思?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多