2016-01-27 16 views
9

Tôi có một biến đối tượng mô hình trong Trình điều khiển xem nhanh. Điều tôi muốn làm là lúc khởi tạo VC, tôi không có giá trị gì cho nó. Nhưng sau khi một cuộc gọi mạng async tôi có đối tượng mô hình phân tích cú pháp là những gì biến này nên giữ, nhưng từ đó tôi không muốn bất cứ điều gì để thay đổi giá trị của biến mô hình.Cách khởi tạo biến, nhưng sau khi thực hiện, giá trị của nó là cuối cùng

Có thể thực hiện điều đó trong Swift không? nếu có, làm thế nào?

Trả lời

7

Dựa trên Babul Prabhakar câu trả lời, nhưng một chút sạch hơn .

Cách tiếp cận 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" 

Edit: làm cho nó ngắn hơn

Phương pháp 2:

let value: String 
value = "Initial string" 

Tôi đoán phương pháp thứ hai là lựa chọn "built-in" của Swift để khai báo biến một lần. Điều này chỉ có thể xảy ra khi biến được gán ngay sau khi khai báo.

+0

Tôi thích cách tiếp cận này tốt hơn, theo cách tiếp cận của @Babul Prabhakar nếu ** myPrivateVar ** được đặt thành không có người đặt vẫn có thể viết. Cách tiếp cận này đảm bảo rằng sẽ không bao giờ xảy ra. +1 –

+0

Cảm ơn bạn, tôi nghĩ đây là cách tiếp cận gọn gàng và ngắn nhất. – inforeqd

7

Những gì bạn có thể làm là

private var myPrivateVar:String?; 

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

     } 

    } 
    get { 
     return myPrivateVar!; 
    } 
} 
0

Tôi sợ không có cách truyền thống trong Swift, và một trong hai bằng các ngôn ngữ khác quá. (Cách truyền thống ở đây có nghĩa là bạn sử dụng từ khóa được hỗ trợ cho mục đích của bạn). Rất khó để bạn biết biến này đã được khởi tạo trước đó (không sử dụng một số biến trạng thái để kiểm tra).

Bạn có thể sử dụng mẫu thiết kế này: khai báo tất cả các thuộc tính là private (vì vậy bạn không thể đặt các thuộc tính đó ở nơi khác trong mã của bạn). Và bạn sẽ khởi tạo tất cả các thuộc tính trong constructor. Vì vậy, tất cả các thuộc tính sẽ được khởi tạo chỉ một.

Objective-CSwift 2 có quyền truy cập modifier như publicprotectedprivate.

lưu ý: Swift 1 không có công cụ sửa đổi truy cập.

Dưới đây là bản demo trong Swift 2:

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

    init (firstName: String, lastName: String) { 
     self.firstName = firstName 
     self.lastName = lastName 
    } 
} 

Dưới đây là bản demo trong 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 

Hope trợ giúp này :)

1

Tôi đích thân đi với câu trả lời của @ Eendje. Với phương pháp tiếp cận @Babul Prabhakar nếu myPrivateVar bằng cách nào đó được đặt thành nil thì setter có thể vẫn ghi hai lần. Tôi muốn chia sẻ một tùy chọn khác là guaranteed để không bao giờ được đặt hai lần (miễn là mã thông báo không bao giờ được ghi vào!):

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 
     } 
    } 

Các dispatch_once() chức năng cung cấp một cơ chế đơn giản và hiệu quả để chạy một initializer chính xác một lần, tương tự như pthread_once (3). Mã được thiết kế tốt che giấu việc sử dụng khởi tạo lười biếng. Ví dụ: Ví dụ:

source

0

hỗ trợ Swift biến lười biếng. Ví dụ: biến sau sẽ được đặt thành giá trị "Xin chào!" chỉ khi được truy cập.

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


// myString gets initialized here since value is been accessed. 
var someOtherVariable = myString 
Các vấn đề liên quan