Swift结构体中调用loadJson初始化属性报错的解决方法及原因
错误原因
当你在结构体定义中直接初始化存储属性(如 var ToDoListData: [ToDoList] = loadJson("sample.json"))时,这个初始化操作发生在结构体实例完全创建之前。而实例方法 loadJson 需要依赖已初始化完成的 self 才能调用,因此此时无法使用该方法,导致报错。
解决方法
方法一:将 loadJson 改为静态方法
静态方法属于结构体类型本身,而非实例,因此无需依赖 self 即可调用。修改后可以直接用静态方法初始化属性:
struct ToDoManager { var toDoListData: [ToDoList] = Self.loadJson("sample.json") static func loadJson<T: Decodable>(_ filename: String) -> T { let data: Data guard let file = Bundle.main.url(forResource: filename, withExtension: nil) else { fatalError("\(filename) not found.") } do { data = try Data(contentsOf: file) } catch { fatalError("Could not load \(filename): \(error)") } do { return try JSONDecoder().decode(T.self, from: data) } catch { fatalError("Unable to parse \(filename): \(error)") } } }
方法二:使用延迟加载属性
标记属性为 lazy 后,它会在第一次被访问时才完成初始化,此时结构体实例已经创建完成,self 可用,因此可以调用实例方法:
struct ToDoManager { lazy var toDoListData: [ToDoList] = loadJson("sample.json") func loadJson<T: Decodable>(_ filename: String) -> T { let data: Data guard let file = Bundle.main.url(forResource: filename, withExtension: nil) else { fatalError("\(filename) not found.") } do { data = try Data(contentsOf: file) } catch { fatalError("Could not load \(filename): \(error)") } do { return try JSONDecoder().decode(T.self, from: data) } catch { fatalError("Unable to parse \(filename): \(error)") } } }
注意:按照Swift命名规范,属性名建议以小写字母开头(如
toDoListData),以区分类型名。
内容的提问来源于stack exchange,提问作者Teol
相关产品推荐
相关产品推荐

