ios - Swift : use of 'self' in method call before super. init初始化自编译报错

标签 ios delegates protocols

我创建了一个处理音频录制/播放的自定义类,并在该类中放置了一个Protocol。我在 UIViewController 类中实现了 Protocol 并为我的 AudioHelper 类调用了我的 setDelegate 方法。

我收到一个与我的 init() 有关的编译错误。不确定如何消除错误:

在 super.init 初始化 self 之前在方法调用“setupAudioSession”中使用“self”

override init() {
        setupAudioSession()
        super.init()
    }

如何解决此错误?为什么我必须覆盖 init()?

我的 AudioHelper 类

import Foundation
import AVFoundation

class AudioHelper: NSObject, AVAudioRecorderDelegate {

    var audioSession: AVAudioSession?
    var audioRecorder: AVAudioRecorder?
    var delegate: AudioRecorderProtocol?

    class var sharedInstance: AudioHelper {

        struct Static {
            static var instance: AudioHelper?
            static var token: dispatch_once_t = 0
        }

        dispatch_once(&Static.token) {
            Static.instance = AudioHelper()
        }

        return Static.instance!
    }

    override init() {
        setupAudioSession()
        super.init()
    }

    func setDelegate(delegate: AudioRecorderProtocol) {
        self.delegate = delegate
    }

    func setupAudioSession() {
        audioSession = AVAudioSession.sharedInstance()
        audioSession?.setCategory(AVAudioSessionCategoryPlayAndRecord, error: nil)
        audioSession?.setActive(true, error: nil)
    }

    func createAudioMessageDirectory() {
        let fm = NSFileManager.defaultManager()
        if !fm.fileExistsAtPath(GlobalVars.kAudioMessageDirectory) {
            var error: NSError?
            if !fm.createDirectoryAtPath(GlobalVars.kAudioMessageDirectory, withIntermediateDirectories: true, attributes: nil, error: &error) {
                println("Unable to create audio message directory: \(error)")
            }
        }
    }

    // MARK: Recording

    func beginRecordingAudio() {
        createAudioMessageDirectory()
        var filepath =  GlobalVars.kAudioMessageDirectory.stringByAppendingPathComponent("audiofile.aac")
        var url = NSURL(fileURLWithPath: filepath)

        var recordSettings = [
            AVFormatIDKey: kAudioFormatMPEG4AAC,
            AVSampleRateKey: 8000.0,
            AVNumberOfChannelsKey: 1,
            AVEncoderBitRateKey: 12800,
            AVLinearPCMBitDepthKey: 16,
            AVEncoderAudioQualityKey: AVAudioQuality.Max.rawValue
        ]

        println("Recorded Audio Message Saved: \(url!)")

        var error: NSError?
        audioRecorder = AVAudioRecorder(URL: url, settings: recordSettings as [NSObject : AnyObject], error: &error)

        if error == nil {
            if audioRecorder != nil {
                audioRecorder!.delegate = self
                audioRecorder!.record()
            }
        }
        else {
            println(error!.localizedDescription)
        }
    }

    func stopRecordingAudio() {
        if audioRecorder != nil {
            audioRecorder!.stop()
        }
    }

    func handleRecordAudioButtonLongPressGestureForState(state: UIGestureRecognizerState) {
        if state == UIGestureRecognizerState.Ended {
            stopRecordingAudio()
            delegate?.onRecordAudioStop()
        }
        else if state == UIGestureRecognizerState.Began {
            beginRecordingAudio()
            delegate?.onRecordAudioStop()
        }
    }

    func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {
        println("Record Audio Success: \(flag)")
        delegate?.onRecordAudioFinished()
    }

    func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {
        println("Record Audio Encode Error: \(error.localizedDescription)")
    }

    // MARK: Playback

    func playAudioMessageFromUrl(messageId: String) {
        if let url = NSURL(string: GlobalVars.kUrlAudioMessage + messageId) {
            if let data = NSData(contentsOfURL: url) {
                var error: NSError? = nil
                let audioPlayer = AVAudioPlayer(data: data, error: &error)

                if error == nil {
                    if audioPlayer != nil {
                        audioPlayer.numberOfLoops = 0
                        audioPlayer.volume = 1.0
                        audioPlayer.prepareToPlay()
                        audioPlayer.play()
                    }
                }
                else {
                    println("Audio playback error: \(error?.localizedDescription)")
                }
            }
        }
    }

}

protocol AudioRecorderProtocol {
    func onRecordAudioStart()
    func onRecordAudioStop()
    func onRecordAudioFinished()
}

实现协议(protocol)的我的 UIViewController(剪掉无关代码)

class ChatViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, AudioRecorderProtocol {

    let audioHelper = AudioHelper.sharedInstance

    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    override func viewDidLoad() {
        super.viewDidLoad()

//        addDemoMessages()

        setupGestureRecognizer()
        setupKeyboardObserver()
        setupViews()
        setupTableView()
        audioHelper.setDelegate(self)
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        getUsersFromDb()
        getMessagesFromDb()
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        setCurrentVC()
        tableView.reloadData()

        if partnerUserId != nil && !db.doesUserExist(partnerUserId!) {
            HttpPostHelper.profileGet(userId: partnerUserId!)
        }

        requestMessagesFromServer()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        ViewHelper.scrollTableViewToBottom(tableView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func handleRecordAudioButtonHold(sender: UILongPressGestureRecognizer) {
        audioHelper.handleRecordAudioButtonLongPressGestureForState(sender.state)
    }

    func onRecordAudioStart() {
        dispatch_async(dispatch_get_main_queue(), {
            ViewHelper.showToast(NSLocalizedString("RECORDING", comment: ""))
            self.recordAudioButton.imageView!.image = UIImage(named: "RecordAudioClicked")
        })
    }

    func onRecordAudioStop() {
        dispatch_async(dispatch_get_main_queue(), {
            self.recordAudioButton.imageView!.image = UIImage(named: "RecordAudio")
        })
    }

    func onRecordAudioFinished() {
        HttpPostHelper.messageAudio(partnerUserId: partnerUserId)
    }

    func playAudioFromUrl(sender: UIButton) {
        let messageId = messages[sender.tag].id
        audioHelper.playAudioMessageFromUrl(messageId)
    }

}

最佳答案

只需将它放在 super.init() 下即可。

该对象需要先由父类(super class)初始化,然后您可以进行自定义初始化。

override init() {
    super.init()
    setupAudioSession()
}

关于ios - Swift : use of 'self' in method call before super. init初始化自编译报错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29904537/

相关文章:

ios - UIWebView 委托(delegate)不会在自定义类中触发

c# - 在 c# 中替代 switch 语句调用方法

networking - 为什么 TCP 段中的 SYN 或 FIN 位占用序列号空间中​​的一个字节?

ios - Firebase 中的多个句柄

ios - 当我使用 transform 属性旋转 UIImageView 时,边缘像素化

ios - 在 Swift 中使用 Twilio 发送短信

java - android 屏幕作为内联网中的 pc 触摸板

ios - 无法约束将 UIView 固定到单元格 contentView 的底部

ios - 是否有必要在 swift iOS 中使用扩展来定义委托(delegate)方法

java - Netty:处理许多不同的数据包类型