Swift 如何初始化变量,但一旦初始化,其值就是最终值

Swift 如何初始化变量,但一旦初始化,其值就是最终值,swift,Swift,我在Swift View控制器中有一个模型对象变量。我想做的是,在VC的初始化阶段,我没有它的价值。但是在异步网络调用之后,我得到了解析的模型对象,这就是这个变量应该保存的对象,但是从那时起,我不希望任何事情改变模型变量的值 是否有可能在Swift中这样做?如果是,怎么做?您可以做的是 private var myPrivateVar:String?; var publicGetter:String { set { if myPrivateVar == nil {

我在Swift View控制器中有一个模型对象变量。我想做的是,在VC的初始化阶段,我没有它的价值。但是在异步网络调用之后,我得到了解析的模型对象,这就是这个变量应该保存的对象,但是从那时起,我不希望任何事情改变模型变量的值

是否有可能在Swift中这样做?如果是,怎么做?

您可以做的是

private var myPrivateVar:String?;

var publicGetter:String {
    set {
        if myPrivateVar == nil {
            myPrivateVar = newValue;

        }

    }
    get {
        return myPrivateVar!;
    }
}
恐怕在Swift中没有传统的方式,在其他语言中也没有。(这里的传统方式意味着您需要使用支持的语言关键字)。您很难知道这个变量以前已经初始化过(不使用某些状态变量进行检查)

您可以使用此设计模式:将所有属性声明为
private
(因此无法在代码中的其他地方设置这些属性)。您将在
构造函数中初始化所有属性。因此,所有属性将仅初始化一个

Objective-C
Swift 2
具有访问修饰符,如
public
受保护
私有

注意
Swift 1
没有访问修饰符

下面是
Swift 2中的演示:

class ViewModel {
    private var firstName : String;
    private var lastName : String;

    init (firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
}
下面是
Objective-C
中的演示:

@interface ViewModel : NSObject
    {
        @private
        NSString *firstName;   
        @private
        NSString *lastName;
    }      
    - (id)initWithFirstName:(NSString *)_firstName
                   lastName:(NSString *)_lastName       
    @end

    @implementation ViewModel     
    - (id)initWithFirstName:(NSString *)_firstName
                   lastName:(NSString *)_lastName
    {
        if( self = [super init] )
        {
            firstName = _firstName;
            lastName = _lastName;
        }       
        return self;
    }        
    @end

希望有帮助:)

基于Babul Prabhakar的回答,但要干净一点

方法1:

var test: String? { didSet { test = oldValue ?? test } }

test = "Initial string"
test = "Some other string"
test = "Lets try one last time"

print(test) // "Initial string"
编辑:缩短了

方法2:

let value: String
value = "Initial string"

我想第二种方法是Swift的“内置”选项,它只声明一次变量。这只有在声明之后立即分配变量时才可能。

如果
myPrivateVar
以某种方式设置为
nil
,则我个人会选择@Eendje或@Babul-Prabhakar的方法。setter仍然可以写两次。我想分享另一个选项,
保证永远不会设置两次(只要令牌从未写入!):

dispatch_once()函数提供了一种简单有效的机制 完全运行初始值设定项 一次,类似于pthread_once(3)。设计良好的代码隐藏了惰性初始化的使用。例如:示例:


Swift支持惰性变量。 例如,只有在访问时,以下变量才会设置为值“Hi There!”

//变量声明,尚未初始化
lazy var myString=“你好!”
//myString在这里初始化,因为值已被访问。
var someOtherVariable=myString

涉及didSet的首要答案是容易出错的-调用者可能会尝试设置变量,但不会收到忽略新值的通知,这可能会导致以后出现各种难以修复的错误

假设您希望该值为非零:

var test: String! {
    willSet(newTest) {
        guard test == nil, newTest != nil else { fatalError("value was already set") }
    }
}

我更喜欢这种方法,在@Babul-Prabhakar的方法中,如果myPrivateVar设置为nil,setter仍然可以编写。这种方法保证了这种情况永远不会发生+1谢谢,我认为这是最干净、最短的方法。我认为第一种方法在类或结构中不起作用,因为它会自动初始化为nil。只是一个提醒。
var test: String! {
    willSet(newTest) {
        guard test == nil, newTest != nil else { fatalError("value was already set") }
    }
}