0

我正在关注一个苹果文档,但不幸的是示例是在objective-c上编写的,但是我对Swift语言有信心,并且无法理解某些东西的含义,特别是在这个示例中:

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

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

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

info: UnsafeMutableRawPointer?

现在,该RunLoopSource* obj = (RunLoopSource*)info;行表明 obj 是一个类型为 RunLoopSource 的变量,并为此分配了 的值(RunLoopSource *) info,但确切地说,这个语句是什么意思?: (RunLoopSource *) info,以及它是如何翻译成 swift 语言的?

4

3 回答 3

3

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

func RunLoopSourcesPerformRoutine(info: UnsafeMutableRawPointer) {
    let obj = info.assumingMemoryBound(to: RunLoopSource.self)
    obj.pointee.sourceFired()
}
于 2016-12-22T18:36:56.587 回答
2

这个特定的表达式是一个“类型转换”:它是说info,被声明为指向未知的指针(void *)实际上被程序员知道是指向 a 的指针RunLoopSource。这会强制更改表达式的类型,以使编译器在分配给obj.

它等同于as!在 Swift 中使用,并且当您知道a 的语义void *但语法没有捕捉到它时,它是惯用的。

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

于 2016-12-22T17:49:19.940 回答
1

您正在处理的 ( void *info) 是 C指向 void的指针,它作为 UnsafeRawPointer 的一种形式进入 Swift。这意味着类型信息已被丢弃,内存正在其他地方进行管理。

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

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

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

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

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

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

于 2016-12-22T18:53:22.283 回答