Swift结构体初始化报错:Variable self.record used before being initialized
问题原因与解决方法
问题根源
报错Variable self.record used before being initialized的核心原因是初始化器的参数名与结构体存储属性名重名,导致Swift编译器在初始化流程中出现混淆,误判你在给self.record赋值前就已经访问了该属性。
解决方法
有两种简单的修复方式,任选其一即可:
方法1:修改初始化器参数名,避免重名
将第一个初始化器的参数名改为与属性名不同的名称(比如ckRecord),消除编译器的混淆:
struct MyAccount: Hashable ,Identifiable, CloudItem { var record: CKRecord var id = UUID() var network: NetworksDataModel.Networks var username: String init?(ckRecord: CKRecord) { guard let newNetworkString = ckRecord.object(forKey: "network") as? String else { return } guard let newNetwork = NetworksDataModel.Networks(rawValue: newNetworkString) else { return } guard let newUsername = ckRecord.object(forKey: "username") as? String else { return } self.network = newNetwork self.username = newUsername self.record = ckRecord } init?(network: NetworksDataModel.Networks, username: String) { let record = CKRecord(recordType: "account") record["network"] = network.rawValue record["username"] = username self.init(ckRecord: record) } }
方法2:先给record属性赋值,再处理其他逻辑
调整赋值顺序,先完成self.record的赋值,再执行后续的guard校验:
struct MyAccount: Hashable ,Identifiable, CloudItem { var record: CKRecord var id = UUID() var network: NetworksDataModel.Networks var username: String init?(record: CKRecord) { self.record = record // 优先完成record属性的赋值 guard let newNetworkString = record.object(forKey: "network") as? String else { return } guard let newNetwork = NetworksDataModel.Networks(rawValue: newNetworkString) else { return } guard let newUsername = record.object(forKey: "username") as? String else { return } self.network = newNetwork self.username = newUsername } init?(network: NetworksDataModel.Networks, username: String) { var record = CKRecord(recordType: "account") record["network"] = network.rawValue record["username"] = username self.init(record: record) } }
补充说明
不需要将CKRecord设为可选类型——你的业务逻辑中record是实例必须的属性,保持非可选类型更符合设计逻辑,也能避免后续代码的可选解包成本。
内容的提问来源于stack exchange,提问作者Ben Kuryk
相关产品推荐
相关产品推荐

