由于我是移动/面向对象编程的初学者,我遇到了一种困惑的情况,让我怀疑我是否正确地编码了.
主修班:
class ViewController: UIViewController, SoundAnalyserDelegate{
lazy var fontSize : SoundAnalyser = {
return SoundAnalyser(delegate: self)
}()
@IBOutlet var frequencyLabel: UILabel!
@IBOutlet var amplitudeLabel: UILabel!
@IBOutlet var note: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
soundAnalyser.start()
}
func setLabelAmp (_ text:String) {
frequencyLabel.text = text
}
func setLabelFreq (_ text:String) {
frequencyLabel.text = text
}
func setLabelNote (_ text:String) {
frequencyLabel.text = text
} 第二类:
class SoundAnalyser {
var delegate:SoundAnalyserDelegate?
let minimum = Double(160)
let maximum = Double(1400)
var mic: AKMicrophone
var tracker: AKFrequencyTracker
fileprivate var silence: AKBooster
fileprivate var timer: Timer?
fileprivate var notesArray: [(String, Double)]?
init(delegate: SoundAnalyserDelegate){
mic = AKMicrophone()
tracker = AKFrequencyTracker(mic, hopSize: minimum, peakCount: maximum)
silence = AKBooster(tracker, gain:0)
notesArray = self.getNotesFrequencies()
self.delegate = delegate
}
func tick(){
let amp = tracker.amplitude
let freq = tracker.frequency
if amp > 0.05 && freq > minimum && freq < maximum{
let readNote = notesArray![analyseCapturedSound()]
delegate?.setLabelAmp(String(format:"%f", amp)) //Setting the text of a label from the UI
delegate?.setLabelFreq(String(format:"%f", freq))
// delegate?.setLabelNote(String(format:"%f", readNote))
print("freq:", freq," amp:", amp," NOTE: \(readNote)")
}
} 我只是加入了最重要的代码来表达我想要问的问题。
摘要:类ViewController启动SoundAnalyser。在SoundAnalyser下,有一个函数可以执行来自ViewController的函数(“delegate?.setLabel.”)。我用了一个使用协议的委托类,但我不知道为什么我觉得出了问题。我是说,执行创建者的方法.是对的吗?如果不是,什么是最“好公民”的方式来实现具有相同结果的东西?
发布于 2017-04-15 13:15:25
这基本上是正确的。使用委托的理由是类应该通知它的委托,而不是指示它。这的一个症状是SoundAnalyser正在格式化文本,这应该是视图控制器的责任。
考虑到SoundAnalyzer在MVC模式中填充了模型的角色。该模型只负责提供数据,不应涉及重新解释数据以供显示。
如果需要在多个地方使用该功能,则可以使用helper类封装格式。
SoundAnalyserDelegate:委托方法采用咨询通知或事件的形式,而不是指令。委托接收数据,而不是预先格式化的文本。如果频率和振幅总是同时变化的话,通过传递聚合对象可以进一步改进这一点(情况似乎是这样):
struct SoundAnalyserSample {
let frequency: Double
let amplitude: Double
}
protocol SoundAnalyserDelegate {
func soundAnalyserSample(sample: SoundAnalyserSample)
// ... and so on
}SoundAnalyser:通知传递示例的委托。
func tick(){
let amp = tracker.amplitude
let freq = tracker.frequency
if amp > 0.05 && freq > minimum && freq < maximum {
let readNote = notesArray![analyseCapturedSound()]
let sample = SoundAnalyserSample(
frequency: freq,
amplitude: amp
}
delegate?.soundAnalyserSample(sample: sample)
}
}ViewController:视图控制器响应发件人的通知(在本例中是声音分析器),格式化数据,并更新UI。请注意,您还需要确保UI更新发生在主队列上,这不一定是由调用方保证的。
class ViewController: UIViewController, SoundAnalyserDelegate {
func soundAnalyserSample(sample: SoundAnalyserSample) {
DispatchQueue.main.async {
let frequencyText = String(format:"%f", sample.frequency)
let amplitudeText = String(format:"%f", sample.amplitude)
frequencyLabel.text = frequencyText
amplitudeLabel.text = amplitudeText
}
}https://codereview.stackexchange.com/questions/157263
复制相似问题