需要self来在init中设置swift类的所有常量

 的闪客快打 发布于 2023-01-09 12:10

我有一个具有常量ivar的Swift类(它们现在被称为实例常量吗?).要将值设置为此常量,我需要调用所需对象的初始化程序并传递自身.但是,我不被允许,因为我需要首先初始化所有值,然后调用super.init(),之后我被允许访问self.那么在这种情况下该怎么办?

class Broadcaster: NSObject, CBPeripheralManagerDelegate {

    let broadcastID: NSUUID
    let bluetoothManager: CBPeripheralManager

    init(broadcastID: NSUUID) {
        self.broadcastID = broadcastID

        let options: Dictionary = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
        self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options) // error: 'self' used before super.init call

        super.init()
    }
}

eofster.. 34

更新Swift 1.2及更高版本

不幸的是,似乎不再可能具有bluetoothManager常数.从Swift 1.2开始,在初始化程序中,常量属性只能赋值一次.这不允许我们nil通过将其声明为可选值并在稍后的初始化过程中更改它来启动值.这是带有bluetoothManager变量的更新版本.

class Broadcaster: NSObject, CBPeripheralManagerDelegate {

    let broadcastID: NSUUID
    var bluetoothManager: CBPeripheralManager!

    init(broadcastID: NSUUID) {
        self.broadcastID = broadcastID
        super.init()
        let options: Dictionary = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
        self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options)
    }
}

原始答案

您可以在此处使用隐式展开的可选(for bluetoothManager),并在以下情况下为其指定值super.init():

class Broadcaster: NSObject, CBPeripheralManagerDelegate {

    let broadcastID: NSUUID
    let bluetoothManager: CBPeripheralManager!

    init(broadcastID: NSUUID) {
        self.broadcastID = broadcastID
        super.init()
        let options: Dictionary = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
        self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options)
    }
}

因为bluetoothManager是可选的,所以super.init()在调用时,所有属性都被初始化(bluetoothManager隐式初始化nil).但是因为我们知道bluetoothManager在初始化类之后肯定会有值,所以我们将它声明为显式解包以避免在使用它时进行检查.

UPDATE

属性可以声明为常量,并且仍然可以在初始化程序中更改.在初始化完成时,必须确保它具有确定的值.这在Swift book的"在初始化期间修改常量属性"一章中有记录.

在需要从尚未完全初始化的对象传递self的调用初始化属性的情况在"无主引用和隐式展开的可选属性"一章中进行了描述.

1 个回答
  • 更新Swift 1.2及更高版本

    不幸的是,似乎不再可能具有bluetoothManager常数.从Swift 1.2开始,在初始化程序中,常量属性只能赋值一次.这不允许我们nil通过将其声明为可选值并在稍后的初始化过程中更改它来启动值.这是带有bluetoothManager变量的更新版本.

    class Broadcaster: NSObject, CBPeripheralManagerDelegate {
    
        let broadcastID: NSUUID
        var bluetoothManager: CBPeripheralManager!
    
        init(broadcastID: NSUUID) {
            self.broadcastID = broadcastID
            super.init()
            let options: Dictionary<String, AnyObject> = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
            self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options)
        }
    }
    

    原始答案

    您可以在此处使用隐式展开的可选(for bluetoothManager),并在以下情况下为其指定值super.init():

    class Broadcaster: NSObject, CBPeripheralManagerDelegate {
    
        let broadcastID: NSUUID
        let bluetoothManager: CBPeripheralManager!
    
        init(broadcastID: NSUUID) {
            self.broadcastID = broadcastID
            super.init()
            let options: Dictionary<NSString, AnyObject> = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
            self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options)
        }
    }
    

    因为bluetoothManager是可选的,所以super.init()在调用时,所有属性都被初始化(bluetoothManager隐式初始化nil).但是因为我们知道bluetoothManager在初始化类之后肯定会有值,所以我们将它声明为显式解包以避免在使用它时进行检查.

    UPDATE

    属性可以声明为常量,并且仍然可以在初始化程序中更改.在初始化完成时,必须确保它具有确定的值.这在Swift book的"在初始化期间修改常量属性"一章中有记录.

    在需要从尚未完全初始化的对象传递self的调用初始化属性的情况在"无主引用和隐式展开的可选属性"一章中进行了描述.

    2023-01-09 12:14 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有