Swift 错误调用函数(无法使用实例成员)
我也有一个问题: “无法从捕获上下文的闭包中形成C函数指针” 在我的主类中,我有“detectChangeMidi”,但在这段代码中,当我试图调用一个函数时,我不明白为什么我不能。 (我也不能使用var,我的任何类) 我不是swift方面的专家,那么试着向我解释一下其中的原因。 我使用CoreMidi图书馆 更新: 为了更好地理解,我用minimalist代码替换代码Swift 错误调用函数(无法使用实例成员),swift,function,swift3,Swift,Function,Swift3,我也有一个问题: “无法从捕获上下文的闭包中形成C函数指针” 在我的主类中,我有“detectChangeMidi”,但在这段代码中,当我试图调用一个函数时,我不明白为什么我不能。 (我也不能使用var,我的任何类) 我不是swift方面的专家,那么试着向我解释一下其中的原因。 我使用CoreMidi图书馆 更新: 为了更好地理解,我用minimalist代码替换代码 import Foundation import CoreMIDI class ViewController: UIViewC
import Foundation
import CoreMIDI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
gestionMidi()
//...
}
func gestionMidi() {
//...
let midiNotif:MIDINotifyProc = detectChangeMidi
MIDIClientCreate("Swift3 Test Client" as CFString, midiNotif, nil, &midiClient)
//...
}
func plop(){
print("bla bla bla")
}
let detectChangeMidi: @convention(c) (UnsafePointer<MIDINotification>, UnsafeMutableRawPointer?) -> Swift.Void =
{ midiNotification,unkown in
var notification = midiNotification.pointee
self.plop() //problem here
//...
}
}
<代码>导入基础
进口CoreMIDI
类ViewController:UIViewController{
重写func viewDidLoad(){
super.viewDidLoad()
gestionMidi()
//...
}
func gestionMidi(){
//...
让midiNotif:MIDINotifyProc=detectChangeMidi
midclientcreate(“Swift3测试客户端”作为CFString、midiNotif、nil和midclient)
//...
}
func plop(){
打印(“布拉布拉布拉布拉”)
}
让detectChangeMidi:@convention(c)(UnsafePointer,unsafemeutablerawpointer?->Swift.Void=
{MIDI通知,在中未知
var notification=midiNotification.pointee
self.plop()//这里有问题
//...
}
}
从错误消息中可以判断,问题出在范围上 另外需要注意的是,您正在闭包中执行
plop()
,这需要self.plop()
另外,midiNotification,unknown in
-unknown
似乎是一个打字错误
检查在何处声明函数本身。从这个片段很难理解您的声明范围。您在这里的整个议程都被误导了;你可以尝试做什么,这一点都不明显。不能将属性或函数声明为
约定(c)
,也不能引用self
。但是你不需要!如果您的目标是将一个函数作为一个参数传递,其中需要一个指向函数的C指针,那么只需传递该函数即可。无论如何,如果你调用midclientcreatewithblock(:::)
,你在Swift中会轻松得多。了解发生了什么更好?对于形式:miditifyproc=(UnsafePointer,UnsafeMutableRawPointer?->void,您不能在实例属性声明中引用self。没有self,我也有一个问题:实例成员“plop”不能用于类型“ViewController”;你的意思是使用这种类型的值吗?@matt,它不是重复的,如果我使用“lazy var…”。我有一些问题。即使你没有显式地说self
,你也在隐式地指self。你不能那样做。它是复制品;这是完全相同的规则。唯一的区别是您的初始值设定项是一个匿名函数体。您可以很容易地将其简化为这样一个非常简单的测试用例:classmyclass{func myMethod(){};让myProperty={myMethod()}
这就是您正在做的,它是非法的。这是一个很好的文档。你是对的,你不能对C函数指针使用lazy
。但是,只需以其他方式表示这个C函数指针,而不是作为实例属性。无论如何,convention(c)
适用于类型,而不是声明,因此您试图做的事情并不明显。如果您试图调用约定(c)
函数,只需调用它即可。如果您试图编写约定(c)
函数,则必须用c编写。您可以声明类型为@convention(c)(arg\u types…->return\u type
)的属性,但它无法捕获上下文,即您不能使用self
。在我看来像是一个复制品。@MartinR哇。一如既往地谢谢你。有没有关于这个的错误文件但是,我仍然认为OP不需要声明这样一个属性,调用midclientcreatewithblock(::::)
而不是过时的midclientcreate(::)
会更好。什么bug?midclientcreate()接受一个C函数回调,您可以传递一个文本闭包,或者一个全局函数,或者(这里)一个约定(C)闭包。但该C回调无法捕获上下文(因为它只是一个函数指针)MIDIClientCreateWithBlock是正确的,它需要一个可以捕获上下文的块。@MartinR很公平。非常感谢,我理解我的代码和MIDIClientCreateWithBlock(:::)的问题所在,我没有问题,它确实更好、更简单。