Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 快速切换模型,使其仅可瞬间读取_Ios_Swift_Xcode_Cocoa Touch_Immutability - Fatal编程技术网

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(由于模型的验证已经存在,因此应该可以工作)为什么不从类的不可变版本开始呢?就像字符串和可变字符串、数组和可变数组等等。因此,没有人可以保留对模型的可变引用。此外,无论如何,您不应该允许直接访问模型属性。所有属性都应该是访问器私有的。因此,访问器可以锁定门。