Swift 等同于 C++ 指针/引用约定?
Swift equivalent of C++ Pointer / Reference convention?
作为一名 C++ 开发人员开始学习 Swift,我想知道如何在结构或其他 class 中将 "pointer" 或 "reference" 存储到属性 的另一个对象的另一个 class。
例如- controlResponder
class(或结构)侦听事件以修改 effect
[=37= 中目标的值 target
].
控制响应者:
struct controlResponder {
var ccNum : Int! // CC number to respond to
var target : Double! // Points to the variable of another object
var min : Double!
var max : Double!
}
效果,在我的例子中,可以是不同的 classes 但将要修改的目标将始终是 Double
(准确地说 - 我正在使用 AudioKit并且我正在瞄准像 AKVariableDelay.time
或 AKMoogLadderFilter.cutoff
)
这样的效果
任何见解将不胜感激,谢谢!
下面是我的一些实际(非功能)代码的删节版:
import Foundation
import AudioKit
import SwiftyJSON
class Effect : AKNode, AKMIDIListener {
enum CustomError: Error {
case badEffectName
}
struct ccListener {
var ccNum : Int!
var target : Int!
var min : Double!
var max : Double!
}
var listeners : [ccListener]
var effectType = ""
var effect = AKNode()
var channel = 0
var midi : AKMIDI
init(connectionInput : AKNode, midi : AKMIDI, subJson : JSON, channel : Int) throws {
self.midi = midi
self.channel = channel
var insertType = subJson["type"]
if insertType == "distortion" {
print("Adding a DISTORTION")
effect = AKTanhDistortion(connectionInput)
if let efx = effect as? AKTanhDistortion {
let gainVal = random(subJson["gain random low"].doubleValue, subJson["gain random high"].doubleValue)
print("gainVal: \(gainVal)")
efx.pregain = gainVal
}
}
else if insertType == "moog" {
print("Adding a MOOG FILTER")
/// CUTOFF
let cutoffVal = random(subJson["cutoff random low"].doubleValue, subJson["cutoff random high"].doubleValue)
print("cutoffVal: \(cutoffVal)")
/// RESONANCE
let resonanceVal = random(subJson["resonance random low"].doubleValue, subJson["resonance random high"].doubleValue)
print("resonanceVal: \(resonanceVal)")
effect = AKMoogLadder(connectionInput,
cutoffFrequency: cutoffVal,
resonance: resonanceVal)
}
else {
print("BAD EFFECT TYPE: \(insertType)")
throw CustomError.badEffectName
}
/////// MIDIZ
midi.openInput("vIn")
super.init()
for (key, cc) in subJson["ccs"] as JSON {
let efx = effect as! AKMoogLadder
listeners.append(ccListener(ccNum: cc["cc number"].intValue, target: efx.cutoffFrequency, min: cc["min"].doubleValue, max: cc["max"].doubleValue))
}
midi.addListener(self)
print("End of Effect init()")
}
func receivedMIDIController(_ controller: MIDIByte, value: MIDIByte, channel: MIDIChannel) {
print("Self channel: \(self.channel), incoming channel: \(Int(channel))")
if self.channel == Int(channel){
print("Effect got a CC!")
}
}
func changeVal(ccNum: Int, newValue: Int) {
for listener in listeners {
if listener.ccNum == ccNum {
listener.target = newValue
}
}
}
}
在Swift中,唯一可以可靠存储的指针是分配给UnsafeMutablePointer.allocate
. The pointers that you can get from the address-of operator and withUnsafeMutablePointer
的指针,它们是作弊的,它们只在短时间内有效;超出该点使用它们将产生不可预测的结果。
这意味着,一般来说,您不能存储指向使用“automatic storage”(借用 C++ 术语)分配的值类型(struct
实例)的指针。如果您需要共享值类型,则需要在某个方便的级别将它们包装在引用类型中(class
个实例)。
您可以获得的最通用的方法是使用一对闭包,一个 returns 值,另一个设置它。但是,对于您的特定情况,可能有一种不太通用但更有用的方法。
作为一名 C++ 开发人员开始学习 Swift,我想知道如何在结构或其他 class 中将 "pointer" 或 "reference" 存储到属性 的另一个对象的另一个 class。
例如- controlResponder
class(或结构)侦听事件以修改 effect
[=37= 中目标的值 target
].
控制响应者:
struct controlResponder {
var ccNum : Int! // CC number to respond to
var target : Double! // Points to the variable of another object
var min : Double!
var max : Double!
}
效果,在我的例子中,可以是不同的 classes 但将要修改的目标将始终是 Double
(准确地说 - 我正在使用 AudioKit并且我正在瞄准像 AKVariableDelay.time
或 AKMoogLadderFilter.cutoff
)
任何见解将不胜感激,谢谢!
下面是我的一些实际(非功能)代码的删节版:
import Foundation
import AudioKit
import SwiftyJSON
class Effect : AKNode, AKMIDIListener {
enum CustomError: Error {
case badEffectName
}
struct ccListener {
var ccNum : Int!
var target : Int!
var min : Double!
var max : Double!
}
var listeners : [ccListener]
var effectType = ""
var effect = AKNode()
var channel = 0
var midi : AKMIDI
init(connectionInput : AKNode, midi : AKMIDI, subJson : JSON, channel : Int) throws {
self.midi = midi
self.channel = channel
var insertType = subJson["type"]
if insertType == "distortion" {
print("Adding a DISTORTION")
effect = AKTanhDistortion(connectionInput)
if let efx = effect as? AKTanhDistortion {
let gainVal = random(subJson["gain random low"].doubleValue, subJson["gain random high"].doubleValue)
print("gainVal: \(gainVal)")
efx.pregain = gainVal
}
}
else if insertType == "moog" {
print("Adding a MOOG FILTER")
/// CUTOFF
let cutoffVal = random(subJson["cutoff random low"].doubleValue, subJson["cutoff random high"].doubleValue)
print("cutoffVal: \(cutoffVal)")
/// RESONANCE
let resonanceVal = random(subJson["resonance random low"].doubleValue, subJson["resonance random high"].doubleValue)
print("resonanceVal: \(resonanceVal)")
effect = AKMoogLadder(connectionInput,
cutoffFrequency: cutoffVal,
resonance: resonanceVal)
}
else {
print("BAD EFFECT TYPE: \(insertType)")
throw CustomError.badEffectName
}
/////// MIDIZ
midi.openInput("vIn")
super.init()
for (key, cc) in subJson["ccs"] as JSON {
let efx = effect as! AKMoogLadder
listeners.append(ccListener(ccNum: cc["cc number"].intValue, target: efx.cutoffFrequency, min: cc["min"].doubleValue, max: cc["max"].doubleValue))
}
midi.addListener(self)
print("End of Effect init()")
}
func receivedMIDIController(_ controller: MIDIByte, value: MIDIByte, channel: MIDIChannel) {
print("Self channel: \(self.channel), incoming channel: \(Int(channel))")
if self.channel == Int(channel){
print("Effect got a CC!")
}
}
func changeVal(ccNum: Int, newValue: Int) {
for listener in listeners {
if listener.ccNum == ccNum {
listener.target = newValue
}
}
}
}
在Swift中,唯一可以可靠存储的指针是分配给UnsafeMutablePointer.allocate
. The pointers that you can get from the address-of operator and withUnsafeMutablePointer
的指针,它们是作弊的,它们只在短时间内有效;超出该点使用它们将产生不可预测的结果。
这意味着,一般来说,您不能存储指向使用“automatic storage”(借用 C++ 术语)分配的值类型(struct
实例)的指针。如果您需要共享值类型,则需要在某个方便的级别将它们包装在引用类型中(class
个实例)。
您可以获得的最通用的方法是使用一对闭包,一个 returns 值,另一个设置它。但是,对于您的特定情况,可能有一种不太通用但更有用的方法。