我在Swift View Controller中有一个模型对象变量。我想做的事情是,在初始化VC时,我没有它的价值。但是在异步网络调用之后,我有解析的模型对象,这是该变量应该保存的,但从那时起,我不想要任何东西来改变模型变量的值。
是否有可能在Swift中这样做?如果有,怎么样?
答案 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)。设计良好的代码隐藏了延迟初始化的使用。例如:例如:
答案 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-C
和Swift 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") }
}
}