Objective-C 指针和 swift

Objective-C pointer and swift

我在关注一个apple document,可惜例子是写在objective-c上的,但我对Swift语言有信心,有些东西看不懂,特别是,在这个例子中:

void RunLoopSourcesPerformRoutine (void *info){
    RunLoopSource*  obj = (RunLoopSource*)info;
    [obj sourceFired];
}

这一行:RunLoopSource* obj = (RunLoopSource*)info;

参数:void *info表示info是一个指向void的指针,那么我可以放任意类型数据结构的地址,下面各种apple文档我都看到了这个的翻译:void *info 变成swift 语言是:

info: UnsafeMutableRawPointer?

现在,RunLoopSource* obj = (RunLoopSource*)info;行表示obj是一个类型为RunLoopSource的变量,并给this赋值(RunLoopSource *) info,但是这个语句到底是什么意思呢? : (RunLoopSource *) info,以及它如何翻译成 swift 语言?

这个特定的表达式是一个 "typecast":它说 info,它被声明为一个指向未知的指针(void *)实际上是已知的程序员成为一个指向RunLoopSource的指针。这会强制更改表达式的类型,以使编译器满意,因为它被分配给 obj

它等同于在 Swift 中使用 as! 并且当 你知道 void * 的语义但语法不抓住它。

(这试图按所述回答您的问题,但我不确定您是否正在寻找更多信息。如果是这样,请澄清,我或 Swift 中不安全指针方面的专家可以提供帮助出。)

Swift 真的很讨厌指针。这两行代码可以转换为Swift as

func RunLoopSourcesPerformRoutine(info: UnsafeMutableRawPointer) {
    let obj = info.assumingMemoryBound(to: RunLoopSource.self)
    obj.pointee.sourceFired()
}

您正在处理的 (void *info) 是一个 C 指向空的指针,它以 UnsafeRawPointer 的形式进入 Swift。这意味着类型信息已被丢弃,内存正在别处管理。

为了按照您认为的那样使用这个东西,即 RunLoopSource,您需要将它明确地描述为 RunLoopSource。在 C 中,您将进行转换,如您发布的示例代码所示:(RunLoopSource*)info。在 Swift 中,您 重新绑定

请注意,在您的情况下,由于此 UnsafeMutableRawPointer 已包装在一个 Optional 中,因此整个事情变得更加复杂,并且必须在您可以执行任何操作之前将其解包。

假设,在你的情况下,info 确实是一个绑定到 RunLoopSource 的 UnsafeMutableRawPointer?,你可以说:

let rlsptr = info!.assumingMemoryBound(to: RunLoopSource.self)
let rls = rlsptr.pointee

现在rls一个RunLoopSource,您可以随心所欲地使用它。但是请记住,内存是不受管理的,因此您应该只在此时此地使用它。

编辑 顺便说一下,Apple 有一份关于这整个问题的非常好的文档:https://swift.org/migration-guide/se-0107-migrate.html