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

时间:2016-01-27 05:12:05

标签: swift

我在Swift View Controller中有一个模型对象变量。我想做的事情是,在初始化VC时,我没有它的价值。但是在异步网络调用之后,我有解析的模型对象,这是该变量应该保存的,但从那时起,我不想要任何东西来改变模型变量的值。

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

6 个答案:

答案 0 :(得分:10)

根据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的“内置”选项,用于声明变量一次。只有在声明之后立即分配变量时才可以这样做。

答案 1 :(得分:8)

你能做的是

private var myPrivateVar:String?;

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

        }

    }
    get {
        return myPrivateVar!;
    }
}

答案 2 :(得分:2)

如果myPrivateVar以某种方式设置为nil,那么我会亲自使用@Eendje或@Babul Prabhakar的方法, 仍然可以写两次。我想分享另一个guaranteed选项永远不会被设置两次(只要永远不会写入令牌!):

    private var token: dispatch_once_t = 0

    private var setOnce : String?

    var publicGetter: String {

        set (newValue) {
            dispatch_once(&token) {
                self.setOnce = newValue
            }
        }

        get {
            guard let setOnce = setOnce else {
                return ""
            }
            return setOnce
        }
    }
  

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

source

答案 3 :(得分:1)

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

// variable declaration, not yet initialized
lazy var myString = "Hi There!"


// myString gets initialized here since value is been accessed.
var someOtherVariable = myString

答案 4 :(得分:0)

我担心Swift中没有传统方式,也不会用其他语言。 (这里的传统方式意味着您使用支持的语言关键字为您的目的)。你很难知道这个变量之前已经被初始化了(没有使用一些状态变量进行检查)。

您可以使用此设计模式:将所有属性声明为private(因此不能在代码中的其他位置设置这些属性)。您将初始化constructor中的所有属性。因此,所有属性将仅初始化为一个。

Objective-CSwift 2具有访问修饰符,例如public protected private

注意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

希望这有帮助:)

答案 5 :(得分:0)

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

假设您希望该值不为空:

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