gpt4 book ai didi

ios - swift 中的函数指针

转载 作者:可可西里 更新时间:2023-11-01 00:21:28 28 4
gpt4 key购买 nike

我正在关注这个 tutorial ,尤其是我在用 Swift 语言转换这个函数时遇到了问题:

- (id)init
{
CFRunLoopSourceContext context = {0, self, NULL, NULL, NULL, NULL, NULL,
&RunLoopSourceScheduleRoutine,
RunLoopSourceCancelRoutine,
RunLoopSourcePerformRoutine};

runLoopSource = CFRunLoopSourceCreate(NULL, 0, &context);
commands = [[NSMutableArray alloc] init];

return self;
}

其中,init 函数中的 context 变量给我带来了问题。

在上面的代码中,context 是一个类型为 CFRunLoopSourceContext 的变量,在 apple 文档中这个对象的初始化是 like this

因此,我在初始化时使用了以下代码,重点放在 schedule 参数上:

var context = CFRunLoopSourceContext(version: 0, info: bridge(obj: self) ,
retain: nil,
release: nil,
copyDescription: nil,
equal: nil,
hash: nil,
schedule: RunLoopSourceScheduleRoutine,
cancel: nil,
perform: nil)

函数 RunLoopSourceScheduleRoutine 是这样的:

    func RunLoopSourceScheduleRoutine(info:UnsafeMutableRawPointer? ,rl:CFRunLoop? , mode:CFRunLoopMode?)  {

let obj : RunLoopSource = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
let theContext = RunLoopContext(withSource: obj, andLoop: rl!)
performSelector(onMainThread: #selector(myMethod), with: theContext, waitUntilDone: false)

}

但编译器给我以下错误消息:c 函数指针只能由对“func”或文字闭包的引用形成

即使我做了以下关闭:

let runLoopSourceScheduleRoutine = { (info:UnsafeMutableRawPointer? ,rl:CFRunLoop? , mode:CFRunLoopMode?)-> Void in return

let obj : RunLoopSource = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
let theContext = RunLoopContext(withSource: obj, andLoop: rl!)
performSelector(onMainThread: #selector(myMethod), with: theContext, waitUntilDone: false)

}

我是这样说的:

var context = CFRunLoopSourceContext(version: 0, info: bridge(obj: self) ,
retain: nil,
release: nil,
copyDescription: nil,
equal: nil,
hash: nil,
schedule: runLoopSourceScheduleRoutine,
cancel: nil,
perform: nil)

给我同样的错误。问题是什么 ?任何提示

最佳答案

如果你使用 func RunLoopSourceScheduleRoutine() 作为回调那么它需要是一个全局函数,而不是实例方法。

如果你将回调定义为闭包那么它需要被标记作为纯 C 回调:

let runLoopSourceScheduleRoutine: @convention(c) (UnsafeMutableRawPointer?, CFRunLoop?, CFRunLoopMode?) -> Void =
{ (info, rl, mode) in

let obj = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
// ...
}

或者,将闭包表达式传递给编译器将类型推断为 C 回调:

var context = CFRunLoopSourceContext(version: 0, info: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) ,
retain: nil,
release: nil,
copyDescription: nil,
equal: nil,
hash: nil,
schedule: { (info, rl , mode) in

let obj = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
// ...
}, cancel: nil,
perform: nil)

另请注意,您必须在 obj 上调用该方法,而不是在 self 上调用该方法。我会推荐 GCD 而不是 performSelector(),这允许编译器检查该方法是否被正确调用参数:

let obj = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
let theContext = RunLoopContext(withSource: obj, andLoop: rl!)
DispatchQueue.main.async {
obj.myMethod(theContext)
}

关于ios - swift 中的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41302897/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com