Ios 快速切换模型,使其仅可瞬间读取
我有一个电话号码模型,如下所示:Ios 快速切换模型,使其仅可瞬间读取,ios,swift,xcode,cocoa-touch,immutability,Ios,Swift,Xcode,Cocoa Touch,Immutability,我有一个电话号码模型,如下所示: import UIKit import Foundation struct PhoneValidation : OptionSet { let rawValue: Int static let phoneInValid = PhoneValidation(rawValue: 1 << 0) static let phoneValid = PhoneValidation(rawValue: 1 << 1)
import UIKit
import Foundation
struct PhoneValidation : OptionSet {
let rawValue: Int
static let phoneInValid = PhoneValidation(rawValue: 1 << 0)
static let phoneValid = PhoneValidation(rawValue: 1 << 1)
static let smsValidationAttempted = PhoneValidation(rawValue: 1 << 2)
static let smsValidationFailed = PhoneValidation(rawValue: 1 << 3)
static let smsValidationSuccessful = PhoneValidation(rawValue: 1 << 4) // OTP is successfully validated in backend. The field should be non-editable in this duration
static let smsValidationOTPTriggered = PhoneValidation(rawValue: 1 << 5) // OTP validation triggered. The field should be non-editable in this duration
}
class PhonesViewModel: NSCopying {
public var phoneType: PhoneNumberType = PhoneNumberType.mobile
public var phone: String?
public var code: String?
public var countryCode: String?
public var isValid : PhoneValidation?
func copy(with zone: NSZone? = nil) -> Any {
let copy = PhonesViewModel()
copy.phoneType = phoneType
copy.phone = phone
copy.code = code
copy.countryCode = countryCode
copy.isValid = isValid
return copy
}
}
导入UIKit
进口基金会
结构PhoneValidation:OptionSet{
让rawValue:Int
static let phoneInValid=PhoneValidation(rawValue:1类似的东西怎么样,我认为最好在您的案例中使用属性包装器!以下不是一个精确的解决方案,但可以根据您的需要进行修改/更改
导入UIKit
enum PhoneNumberType {
case mobile
}
enum PhoneValidation {
case phoneInValid
case phoneValid
case smsValidationAttempted
case smsValidationFailed
case smsValidationSuccessful
case smsValidationOTPTriggered
}
struct PhonesViewModel {
public var phoneType: PhoneNumberType = PhoneNumberType.mobile
public var phone: String?
public var code: String?
public var countryCode: String?
public var phoneValidation : PhoneValidation?
func validate(value: [PhoneValidation]) -> Bool {
//add proper check here
return false
}
}
@propertyWrapper
struct Wrapper {
private(set) var value: PhonesViewModel? = nil
var validators: [PhoneValidation] = []
var wrappedValue: PhonesViewModel? {
get { value }
set {
if let model = newValue, model.validate(value: validators) {
value = newValue
print("Value assigned")
} else {
print("Value not assigned")
}
}
}
}
struct SomeOtherClass {
@Wrapper(validators: [PhoneValidation.phoneInValid])
var model: PhonesViewModel?
}
var a = SomeOtherClass()
a.model = PhonesViewModel()
a.model = PhonesViewModel()
您可以使用名为“冰棒不变性”的技术。对象最初是可变的,但可以“冻结”。禁止对冻结对象进行修改。在您的情况下,PhonesViewModel
在isValid
属性具有值smsvalidationtptriggered
或smsValidationSuccessful
时冻结
让我们为对象的需求添加Freezable
协议,这些对象对于PhonesViewModel
来说可能是不可变的和一致的:
protocol-Freezable:class{
var isfreezed:Bool{get}
}
扩展电话可视模型:Freezable{
变量被冻结:Bool{
isValid==.smsValidationTPtriggered | | isValid==.smsValidationSuccessful
}
}
现在,我们必须在分配属性时为isfronged
值添加验证。它可以添加到属性中,如:
。。。
公用电话:字符串{
迪塞特{
验证()
}
}
...
私有函数验证(){
断言(!isfreezed)
}
或使用属性包装器:
@propertyWrapper
结构防护{
私有var值:value
init(wrappedValue:Value){
value=wrappedValue
}
@可用(*,不可用)
var wrappedValue:Value{
get{fatalError(“仅适用于符合Freezable协议的类的实例属性”)}
set{fatalError(“仅适用于符合Freezable协议的类的实例属性”)}
}
静态下标(
_enclosingInstance对象:EnclosingSelf,
包装的wrappedKeyPath:ReferenceWritableKeyPath,
存储密钥路径:引用可写密钥路径
)->价值{
得到{
对象[keyPath:storageKeyPath]。值
}
设置{
前提条件(!object.isfreezed,“对象\(对象)已冻结!禁止修改”)
对象[keyPath:storageKeyPath].value=newValue
}
}
}
因此,您的类将如下所示:
class PhonesViewModel:NSCopying{
@守卫
public var phoneType:PhoneNumberType=PhoneNumberType.mobile
@守卫
公用电话:字符串?
@守卫
公共变量代码:字符串?
@守卫
公共代码:字符串?
@守卫
公共变量isValid:PhoneValidation?
func副本(带区域:NSZone?=nil)->任何{
让copy=PhonesViewModel()
copy.phoneType=phoneType
copy.phone=电话
copy.code=代码
copy.countryCode=countryCode
copy.isValid=isValid
返回副本
}
}
谢谢你的回答。我想这解决了任何模块都无法更改a.model
的问题,这很好。我还需要的是,没有人能够做a.model.phone=“SomeOtherNumber”
也是。这意味着对象的内部属性也应该是只读的。我该怎么做?@RajPawanGumdal这就是我创建struct而不是Class的原因。您可以使用struct吗?因此,如果强制执行struct,则无法修改值,每次如果有人想要更新值,他/她都需要创建一个新的struct(由于模型的验证已经存在,因此应该可以工作)为什么不从类的不可变版本开始呢?就像字符串和可变字符串、数组和可变数组等等。因此,没有人可以保留对模型的可变引用。此外,无论如何,您不应该允许直接访问模型属性。所有属性都应该是访问器私有的。因此,访问器可以锁定门。