Ios &引用;“向下投射”;Swift中的C结构
核心MIDI是一个C API,它提供了其他地方找不到的功能 当用户的MIDI设置发生更改(例如,您插入了设备)时,会发出通知 这是所调用函数的类型Ios &引用;“向下投射”;Swift中的C结构,ios,swift,Ios,Swift,核心MIDI是一个C API,它提供了其他地方找不到的功能 当用户的MIDI设置发生更改(例如,您插入了设备)时,会发出通知 这是所调用函数的类型 typealias MIDINotifyProc = CFunctionPointer<((UnsafePointer<MIDINotification>, UnsafeMutablePointer<Void>) -> Void)> 您可以这样实现回调: struct MIDINotification {
typealias MIDINotifyProc = CFunctionPointer<((UnsafePointer<MIDINotification>, UnsafeMutablePointer<Void>) -> Void)>
您可以这样实现回调:
struct MIDINotification {
var messageID: MIDINotificationMessageID
var messageSize: UInt32
}
func MyMIDINotifyProc (np:UnsafePointer<MIDINotification>, refCon:UnsafeMutablePointer<Void>) {
var notification = np.memory
switch (notification.messageID) {
case MIDINotificationMessageID(kMIDIMsgObjectAdded):
// In Objective-C you would just do a cast here
// This is the problem line
var m = np.memory as MIDIObjectAddRemoveNotification
如您所见,此结构具有附加信息。例如,“child”可能是设备的端点,因此您需要这些字段
问题是从MIDINotification结构(回调签名所需)转换为MIDIObjectAddRemoveNotification。我显示的使用“as”的行不起作用
您对这种“向下转换”有什么建议吗?我建议您研究一下标准库函数。因为
MIDINotification
和MIDIObjectAddRemoveNotification
没有任何继承或契约关系,所以Swift不能在这些结构之间执行任何安全转换
您需要使用unsafeBitCast
函数显式强制转换它:
case MIDINotificationMessageID(kMIDIMsgObjectAdded):
let m = unsafeBitCast(np.memory, MIDIObjectAddRemoveNotification.self)
请注意,此函数始终可以在Swift中用于执行强制转换,但它非常不安全,您只能将其用作最后一种可能的解决方案。您忘记了一件事。即使是Obj-C,投射也总是发生在指针上。你不能将记忆转换为记忆(好吧,有时候你可以,重新解释它,但这不是很安全)
let notification=np.memory
开关(notification.messageID){
案例midNotificationMessageId(kMIDIMsgObjectAdded):
//投下指针!
设addedNp=UnsafeMutablePointer(np)
//现在你可以直接访问内存了
var m=已添加的内存
}
Update:好吧,它工作了一段时间。它现在在Swift 2.0测试版中被打破。
case MIDINotificationMessageID(kMIDIMsgObjectAdded):
let m = unsafeBitCast(np.memory, MIDIObjectAddRemoveNotification.self)
let notification = np.memory
switch (notification.messageID) {
case MIDINotificationMessageID(kMIDIMsgObjectAdded):
//cast the pointer!
let addedNp = UnsafeMutablePointer<MIDIObjectAddRemoveNotification>(np)
//now you can just access memory directly
var m = addedNp.memory
}