Swift 错误调用函数(无法使用实例成员)

Swift 错误调用函数(无法使用实例成员),swift,function,swift3,Swift,Function,Swift3,我也有一个问题: “无法从捕获上下文的闭包中形成C函数指针” 在我的主类中,我有“detectChangeMidi”,但在这段代码中,当我试图调用一个函数时,我不明白为什么我不能。 (我也不能使用var,我的任何类) 我不是swift方面的专家,那么试着向我解释一下其中的原因。 我使用CoreMidi图书馆 更新: 为了更好地理解,我用minimalist代码替换代码 import Foundation import CoreMIDI class ViewController: UIViewC

我也有一个问题: “无法从捕获上下文的闭包中形成C函数指针”

在我的主类中,我有“detectChangeMidi”,但在这段代码中,当我试图调用一个函数时,我不明白为什么我不能。 (我也不能使用var,我的任何类)

我不是swift方面的专家,那么试着向我解释一下其中的原因。 我使用CoreMidi图书馆

更新:

为了更好地理解,我用minimalist代码替换代码

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(:::)的问题所在,我没有问题,它确实更好、更简单。