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
我在关注一个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