Sự hiểu biết của tôi là thiết lập và nhận được cho các thuộc tính được tính toán (không có sự hỗ trợ từ các thuộc tính được lưu trữ )
nếu bạn đến từ một Objective-C trong tâm trí rằng các quy ước đặt tên đã thay đổi. Trong Swift, một biến iVar hoặc cá thể được đặt tên là thuộc tính được lưu trữ
Ví dụ 1 (chỉ đọc thuộc tính) - với cảnh báo:
var test : Int {
get {
return test
}
}
Điều này sẽ dẫn đến một cảnh báo vì điều này dẫn đến một cuộc gọi hàm đệ quy (chính trình gọi getter). Cảnh báo trong trường hợp này là "Cố gắng sửa đổi 'kiểm tra' trong trình getter của chính nó".
Ví dụ 2. Đọc / ghi có điều kiện - có cảnh báo
var test : Int {
get {
return test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
//(prevents same value being set)
if (aNewValue != test) {
test = aNewValue
}
}
}
Vấn đề tương tự - bạn không thể làm điều này vì nó gọi đệ quy setter. Ngoài ra, lưu ý mã này sẽ không phàn nàn về việc không có trình khởi tạo vì không có thuộc tính được lưu trữ để khởi tạo .
Ví dụ 3. đọc / ghi thuộc tính được tính toán - với cửa hàng sao lưu
Dưới đây là mẫu cho phép cài đặt có điều kiện một thuộc tính được lưu trữ thực tế
//True model data
var _test : Int = 0
var test : Int {
get {
return _test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
if (aNewValue != test) {
_test = aNewValue
}
}
}
Lưu ý Dữ liệu thực tế được gọi là _test (mặc dù nó có thể là bất kỳ dữ liệu hoặc kết hợp dữ liệu nào) Lưu ý cũng cần cung cấp một giá trị ban đầu (thay vào đó bạn cần sử dụng một phương thức init) vì thực tế _test là một biến thể
Ví dụ 4. Sử dụng ý chí và đã thiết lập
//True model data
var _test : Int = 0 {
//First this
willSet {
println("Old value is \(_test), new value is \(newValue)")
}
//value is set
//Finaly this
didSet {
println("Old value is \(oldValue), new value is \(_test)")
}
}
var test : Int {
get {
return _test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
if (aNewValue != test) {
_test = aNewValue
}
}
}
Ở đây chúng ta thấy will set và did set chặn một sự thay đổi trong một tài sản được lưu trữ thực tế. Điều này hữu ích để gửi thông báo, đồng bộ hóa, v.v ... (xem ví dụ bên dưới)
Ví dụ 5. Ví dụ cụ thể - Container ViewContoder
//Underlying instance variable (would ideally be private)
var _childVC : UIViewController? {
willSet {
//REMOVE OLD VC
println("Property will set")
if (_childVC != nil) {
_childVC!.willMoveToParentViewController(nil)
self.setOverrideTraitCollection(nil, forChildViewController: _childVC)
_childVC!.view.removeFromSuperview()
_childVC!.removeFromParentViewController()
}
if (newValue) {
self.addChildViewController(newValue)
}
}
//I can't see a way to 'stop' the value being set to the same controller - hence the computed property
didSet {
//ADD NEW VC
println("Property did set")
if (_childVC) {
// var views = NSDictionaryOfVariableBindings(self.view) .. NOT YET SUPPORTED (NSDictionary bridging not yet available)
//Add subviews + constraints
_childVC!.view.setTranslatesAutoresizingMaskIntoConstraints(false) //For now - until I add my own constraints
self.view.addSubview(_childVC!.view)
let views = ["view" : _childVC!.view] as NSMutableDictionary
let layoutOpts = NSLayoutFormatOptions(0)
let lc1 : AnyObject[] = NSLayoutConstraint.constraintsWithVisualFormat("|[view]|", options: layoutOpts, metrics: NSDictionary(), views: views)
let lc2 : AnyObject[] = NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: layoutOpts, metrics: NSDictionary(), views: views)
self.view.addConstraints(lc1)
self.view.addConstraints(lc2)
//Forward messages to child
_childVC!.didMoveToParentViewController(self)
}
}
}
//Computed property - this is the property that must be used to prevent setting the same value twice
//unless there is another way of doing this?
var childVC : UIViewController? {
get {
return _childVC
}
set(suggestedVC) {
if (suggestedVC != _childVC) {
_childVC = suggestedVC
}
}
}
Lưu ý việc sử dụng các thuộc tính được lưu trữ và tính toán. Tôi đã sử dụng một thuộc tính được tính toán để ngăn việc đặt cùng một giá trị hai lần (để tránh những điều xấu xảy ra!); Tôi đã sử dụng will Set và didset để chuyển tiếp thông báo tới viewControllers (xem tài liệu và thông tin về UIViewControll trên các thùng chứa viewContoder)
Tôi hy vọng điều này có ích, và làm ơn ai đó hét lên nếu tôi mắc lỗi ở bất cứ đâu tại đây!
get
&set
) về cơ bản để có một tài sản được tính toán dựa trên một tài sản khác, ví dụ: chuyển đổi nhãntext
thành một nămInt
.didSet
&willSet
ở đó để nói ... này giá trị này đã được đặt, bây giờ hãy thực hiện điều này, ví dụ như DataSource của chúng tôi đã được cập nhật ... vì vậy hãy tải lại bảngView để nó bao gồm các hàng mới. Để biết ví dụ khác, hãy xem câu trả lời của dfri về cách gọi đại biểu vàodidSet