As a C++ dev picking up Swift, I'm wondering how, in a struct or other class, to store a "pointer" or "reference" to a property of of another object of another class.
作为一个c++开发人员,我想知道,在一个结构或其他类中,如何将一个“指针”或“引用”存储到另一个类的另一个对象的属性中。
For example- a controlResponder
class (or struct) that listens for events to modify the value target
of a target in an effect
class.
例如,一个controlResponder类(或struct),它侦听事件以修改effect类中目标的值目标。
Control responder:
控制响应器:
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!
}
Effects, in my case, can be of different classes but the thing that will be targeted for modification will always be a Double
(To be precise- I'm working with AudioKit and am targeting effects like AKVariableDelay.time
, or AKMoogLadderFilter.cutoff
)
在我的例子中,效果可以是不同的类,但是用于修改的目标总是双精度的(准确地说——我正在处理AudioKit,目标是效果,比如AKVariableDelay)。时间,或者AKMoogLadderFilter。截止)
Any insight would be greatly appreciated, thanks!
非常感谢您的理解,谢谢!
Below is an abridged version of some of my actual (non functioning) code:
以下是我的一些实际(非功能)代码的节略版本:
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
}
}
}
}
1 个解决方案
#1
1
In Swift, the only pointers that you can reliably store are those allocated with UnsafeMutablePointer.allocate
. The pointers that you can get from the address-of operator and withUnsafeMutablePointer
are cheats and they are only valid for a short time; using them beyond that point will have unpredictable results.
在Swift中,惟一可以可靠存储的指针是那些使用unsafemutablepointer. allocation分配的指针。你可以从寻址操作符和unsafemutablepointer中获得的指针是欺骗,它们只在短时间内有效;超过这一点使用它们将产生不可预测的结果。
This means that, generally speaking, you can't store a pointer to a value type (struct
instances) that was allocated with "automatic storage" (to borrow from C++ terminology). If you need to share value types, you need to wrap them, at some convenient level, in a reference type (class
instances).
这意味着,通常来说,您不能存储一个指向值类型(struct实例)的指针,该值类型被分配给“自动存储”(借用c++术语)。如果您需要共享值类型,那么您需要在一个引用类型(类实例)中以某种方便的级别包装它们。
The most generic you could get would be to use a pair of closures, one that returns the value and another one that sets it. However, there's probably a less generic but more useful way to do it for your specific case.
最通用的方法是使用一对闭包,一个返回值,另一个设置值。但是,对于特定的情况,可能有一种不太通用但更有用的方法。
#1
1
In Swift, the only pointers that you can reliably store are those allocated with UnsafeMutablePointer.allocate
. The pointers that you can get from the address-of operator and withUnsafeMutablePointer
are cheats and they are only valid for a short time; using them beyond that point will have unpredictable results.
在Swift中,惟一可以可靠存储的指针是那些使用unsafemutablepointer. allocation分配的指针。你可以从寻址操作符和unsafemutablepointer中获得的指针是欺骗,它们只在短时间内有效;超过这一点使用它们将产生不可预测的结果。
This means that, generally speaking, you can't store a pointer to a value type (struct
instances) that was allocated with "automatic storage" (to borrow from C++ terminology). If you need to share value types, you need to wrap them, at some convenient level, in a reference type (class
instances).
这意味着,通常来说,您不能存储一个指向值类型(struct实例)的指针,该值类型被分配给“自动存储”(借用c++术语)。如果您需要共享值类型,那么您需要在一个引用类型(类实例)中以某种方便的级别包装它们。
The most generic you could get would be to use a pair of closures, one that returns the value and another one that sets it. However, there's probably a less generic but more useful way to do it for your specific case.
最通用的方法是使用一对闭包,一个返回值,另一个设置值。但是,对于特定的情况,可能有一种不太通用但更有用的方法。