致命错误:init(coder:) 尚未实现 THEN Property 'self.album'未在 super.init 调用中初始化 THEN 为自身分配属性

发布于 2025-01-12 22:18:01 字数 2933 浏览 0 评论 0原文

因此,我正在创建一个应用程序,其中包含一个音频播放器,一旦用户登录其帐户,就可以通过从主页调用的按钮访问该音频播放器。应用程序的所有页面都是使用 Storyboard 创建的,但音频播放器是使用 SwiftUI 以编程方式完成的。该应用程序运行良好,直到您按下按钮访问音频播放器。然后我在 AudioPlayerViewController 上收到“线程 1:致命错误:init(coder:) 尚未实现”。所以我在网上搜索了一个解决方案,并根据这里的建议,在 stackOverflow 上,删除了这个:

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
} 

并按照建议放置了这个:

  required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
}

但后来我收到此错误:

“属性'self.album'未在 super.init 调用时初始化”

所以我添加:“ self.album = album” - 如下所示:

 required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
    self.album = album

}

但随后我收到错误:“为自身分配属性”

现在我累了。发送帮助。

让我知道我是否应该分享我的代码或其他任何内容的链接,我以前没有在这里问过问题。

我想这就是完整的代码:

import UIKit

final class AudioPlayerViewController: UIViewController {
var album: Album

private lazy var mediaPlayer: MediaPlayer = {
    let v = MediaPlayer(album: album)
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()

init(album: Album) {
    self.album = album
    super.init(nibName: nil, bundle: nil)
}

//    required init?(coder: NSCoder) {
//        fatalError("init(coder:) has not been     implemented")
//    }

required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
    self.album = album

}
//    override func awakeFromNib() {
//       super.awakeFromNib()
//       //custom logic goes here
//    }
//
override func viewDidLoad() {
    super.viewDidLoad()
    setupView()
}

private func setupView() {
    addBlurredView()
    view.addSubview(mediaPlayer)
    
    setupConstraints()
}

private func addBlurredView() {
    if !UIAccessibility.isReduceTransparencyEnabled {
        self.view.backgroundColor = UIColor.clear
        
        let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
        let blueEffectView = UIVisualEffectView(effect: blurEffect)
        blueEffectView.frame = self.view.bounds
        blueEffectView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        
        view.addSubview(blueEffectView)
    } else {
        view.backgroundColor = UIColor.black
    }
}

private func setupConstraints() {
    NSLayoutConstraint.activate([
        mediaPlayer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        mediaPlayer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        mediaPlayer.topAnchor.constraint(equalTo: view.topAnchor),
        mediaPlayer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
    ])
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    mediaPlayer.play()
    UIApplication.shared.isIdleTimerDisabled = true
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    mediaPlayer.stop()
    UIApplication.shared.isIdleTimerDisabled = false
}
}

so I am creating an app that includes an audio player that is accessed through a button called from the main page once the user has logged into their account. All of the pages of the app have been created using Storyboards but the audio player is done programmatically with SwiftUI. The app runs fine until you press the button to access the audio player. Then I get "Thread 1: Fatal error: init(coder:) has not been implemented" on the AudioPlayerViewController. So I searched for a solution online and as per the suggestions here, on stackOverflow, removed this:

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
} 

And put this, instead, as suggested:

  required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
}

But then I get this error:

"Property 'self.album' not initialized at super.init call"

so I add: " self.album = album" - as you see below:

 required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
    self.album = album

}

But then I get the error: "Assigning a property to itself"

And now I'm tired. Send help.

Let me know if I should share a link to my code or whatever else, I haven't asked a question here before.

I guess here's the whole code anyway:

import UIKit

final class AudioPlayerViewController: UIViewController {
var album: Album

private lazy var mediaPlayer: MediaPlayer = {
    let v = MediaPlayer(album: album)
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()

init(album: Album) {
    self.album = album
    super.init(nibName: nil, bundle: nil)
}

//    required init?(coder: NSCoder) {
//        fatalError("init(coder:) has not been     implemented")
//    }

required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
    self.album = album

}
//    override func awakeFromNib() {
//       super.awakeFromNib()
//       //custom logic goes here
//    }
//
override func viewDidLoad() {
    super.viewDidLoad()
    setupView()
}

private func setupView() {
    addBlurredView()
    view.addSubview(mediaPlayer)
    
    setupConstraints()
}

private func addBlurredView() {
    if !UIAccessibility.isReduceTransparencyEnabled {
        self.view.backgroundColor = UIColor.clear
        
        let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
        let blueEffectView = UIVisualEffectView(effect: blurEffect)
        blueEffectView.frame = self.view.bounds
        blueEffectView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        
        view.addSubview(blueEffectView)
    } else {
        view.backgroundColor = UIColor.black
    }
}

private func setupConstraints() {
    NSLayoutConstraint.activate([
        mediaPlayer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        mediaPlayer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        mediaPlayer.topAnchor.constraint(equalTo: view.topAnchor),
        mediaPlayer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
    ])
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    mediaPlayer.play()
    UIApplication.shared.isIdleTimerDisabled = true
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    mediaPlayer.stop()
    UIApplication.shared.isIdleTimerDisabled = false
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

您的好友蓝忘机已上羡 2025-01-19 22:18:01

欢迎来到SO!这个答案不会解决你所有的问题,但它解决了你的问题。一旦克服了这个障碍,您应该随时提出(打开/提交)其他问题。

当编译器抱怨:

“属性‘self.album’未在 super.init 调用时初始化”

时,你说你添加了:

required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
    self.album = album

}

但这并没有解决编译器刚刚抱怨的问题:

属性 self.album 在 super.init 调用时仍未初始化。

您只是将其添加到了错误的位置。
调用super之前初始化self.album:

required init?(coder aDecoder: NSCoder) {
   self.album = album
   super.init(coder: aDecoder) 
}

以下来自Apple的在线文档
AppleDoc

两阶段初始化
Swift 中的类初始化是一个两阶段的过程。在第一阶段,每个存储的属性都由引入它的类分配一个初始值。一旦确定了每个存储属性的初始状态,第二阶段就开始了,在新实例被认为可供使用之前,每个类都有机会进一步自定义其存储属性。

使用两阶段初始化过程可以使初始化安全,同时仍然为类层次结构中的每个类提供完全的灵活性。两阶段初始化可防止属性值在初始化之前被访问,并防止属性值被另一个初始化程序意外设置为不同的值。

Welcome to SO! This answer will not solve all your problems, but it addresses your question. You should feel free to ask (open/submit) additional questions once you get over this speed bump.

When the compiler complained that:

"Property 'self.album' not initialized at super.init call"

You say you added:

required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
    self.album = album

}

But that doesn't address what the compiler just complained about:

The property self.album is still not initialized at super.init call.

You just added it in the wrong place is all.
Initialize self.album before calling super:

required init?(coder aDecoder: NSCoder) {
   self.album = album
   super.init(coder: aDecoder) 
}

The following is from Apple's online documentation
AppleDoc

Two-Phase Initialization
Class initialization in Swift is a two-phase process. In the first phase, each stored property is assigned an initial value by the class that introduced it. Once the initial state for every stored property has been determined, the second phase begins, and each class is given the opportunity to customize its stored properties further before the new instance is considered ready for use.

The use of a two-phase initialization process makes initialization safe, while still giving complete flexibility to each class in a class hierarchy. Two-phase initialization prevents property values from being accessed before they’re initialized, and prevents property values from being set to a different value by another initializer unexpectedly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文