Ios 设置计算值(结构与类)
我制作了一个简单的结构来处理UI背景的管理(用户可以选择使用渐变或图像)。此结构中有一个名为Ios 设置计算值(结构与类),ios,swift,Ios,Swift,我制作了一个简单的结构来处理UI背景的管理(用户可以选择使用渐变或图像)。此结构中有一个名为preference的计算属性,用于获取用户的首选项并将其设置为UserDefaults 当我尝试使用以下代码设置首选项属性时: Background().首选项=.gradient 我收到一个错误:“无法分配给属性:函数调用返回不可变值” 我必须用这个来代替: var background=background() background.preference=.gradient 我希望在最终设置属性之前
preference
的计算属性,用于获取用户的首选项并将其设置为UserDefaults
当我尝试使用以下代码设置首选项
属性时:
Background().首选项=.gradient
我收到一个错误:“无法分配给属性:函数调用返回不可变值”
我必须用这个来代替:
var background=background()
background.preference=.gradient
我希望在最终设置属性之前,不必将Background
的实例分配给变量
我发现将Background
从struct
更改为class
允许我直接使用Background().preference=.gradient
设置属性
有谁能告诉我为什么会发生这种情况?在这种情况下,使用class
比使用struct
更好还是无关紧要
struct Background {
enum Choice {
case gradient
case image
}
var preference: Choice {
get {
if let type = UserDefaults.standard.value(forKey: "background_type"), type as! String == "background" {
return .image
}
return .gradient
}
set(value){
if value == .image {
UserDefaults.standard.setValue("background", forKey: "background_type")
}else{
UserDefaults.standard.setValue("gradient", forKey: "background_type")
}
}
}
将一个结构/类的实例仅仅包装为UserDefaults并没有真正获得任何价值。这是一个非常常见的问题,如果你四处搜索,谷歌上有很多聪明的解决方案。对于一个非常简单的示例,您可以扩展UserDefaults
//: Playground - noun: a place where people can play
import Cocoa
enum BackgroundChoice {
case gradient
case image
}
extension UserDefaults {
var backgroundChoice: BackgroundChoice {
get {
if let type = string(forKey: "background_type"), type == "image" {
return .image
}
return .gradient
}
set(value){
if value == .image {
setValue("background", forKey: "background_type")
}else{
setValue("gradient", forKey: "background_type")
}
}
}
}
UserDefaults.standard.backgroundChoice = .image
我知道这并不能回答您的确切问题,但我想如果您仔细研究,您会发现有更好的解决方案。每次调用
Background()
都会创建一个新的Background
实例,用于唯一(临时)访问/设置UserDefault
值,在你扔掉特定的Background
实例之后。也就是说,您当前有一个值类型,它本身不存储任何内容,只提供对某些特定UserDefault
:s的访问接口。也许您更愿意在这里使用单例或纯类型属性/方法(以替换首选项
)?(请注意,让Background
成为一个类仍然存在相同的问题:您动态构造实例,而实例本身并不拥有任何数据)我的目标是将这种类型的代码从视图控制器移出到单独的文件中,以减少大小并提高可测试性。在这方面,扩展看起来非常有用。谢谢