Swift: use of 'self' in method call before super.init initializes self compile error

怎甘沉沦 提交于 2020-12-25 01:40:21

问题


I made a custom class that handles audio recording/playback and put a Protocol in that class. I implemented the Protocol in a UIViewController class and called my setDelegate method for my AudioHelper class.

I am getting a compile error that has to do with my init(). Not exactly sure how to get rid of the error:

use of 'self' in method call 'setupAudioSession' before super.init initializes self

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

How do I resolve this error? And why do I have to override init()?

My AudioHelper class

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()
}

My UIViewController that implements the protocol (cut out extraneous code)

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)
    }

}

回答1:


Just place it under super.init()

The object needs to be initialized first by super class and then you can do your custom initialization.

So like:

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


来源:https://stackoverflow.com/questions/29904537/swift-use-of-self-in-method-call-before-super-init-initializes-self-compile-e

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!