2013-01-21 44 views
8

Nếu tôi có một tài sản như sauKVO bắn khi giá trị giao là không khác nhau

@property(assign, nonatomic) NSUInteger myValue; 

Và gán một thuộc tính để nó

self.myValue = 2; 

KVO sẽ cháy như mong đợi. Nếu sau này, sau đó tôi chỉ định cùng một giá trị cho nó

self.myValue = 2; 

KVO sẽ kích hoạt lại. Tôi đã cho rằng KVO trong Objective-C sẽ không bắn nếu giá trị được gán không khác nhau. Có vẻ như tôi không chính xác.

Có cách nào để buộc hành vi mặc định này, tức là vô hiệu hóa thông báo KVO kích hoạt mỗi khi giá trị được gán không? Tôi có thể tạo accessors của riêng tôi, nhưng điều này có thể được khá nhiều công việc nếu có rất nhiều tài sản mà tôi muốn thay đổi ...

Cảm ơn bạn đã trả lời.

+0

Nếu điều quan trọng đối với một số lý do là một thông báo cụ thể được chỉ phát sinh khi khi thay đổi giá trị , sau đó bạn cần phải viết một setter tùy chỉnh hoặc kiểm tra giá trị trước khi thiết lập nó. tức là 'if (self.myValue! = 2) self.myValue = 2'. – lnafziger

+0

Một câu hỏi hay và điều ngạc nhiên là điều này không bao giờ được thực hiện rõ ràng trong tài liệu của Apple. – Fattie

Trả lời

13

KVO kích hoạt khi một setter (hoặc bộ đột biến khác) được gọi. Không có kiểm tra bổ sung. Nói chung, KVO cực kỳ nhẹ và hiệu suất nhạy cảm. Vì những thay đổi không cần thiết thường hiếm và trong hầu hết các trường hợp vô hại đối với người quan sát, chúng không bao gồm chi phí phụ trội để kiểm tra giá trị cũ. Kiểm tra giá trị trước đó có thể tốn kém, ví dụ nếu một đối tượng được quản lý không bị lỗi, do đó, thực hiện rất nhiều công việc chỉ để kiểm tra trường hợp này không phải là hành vi mặc định.

Nếu bạn cần kiểm tra xem giá trị đã thay đổi hay không, bạn có thể làm như vậy với người quan sát bằng cách chuyển các tùy chọn NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld. Sau đó, bạn sẽ nhận được cả giá trị mới và cũ và bạn có thể quyết định xem có nên làm gì với thông tin đó hay không. Tôi đã tìm thấy trong thực tế rằng điều này không cần thiết rất thường xuyên, tuy nhiên.

+1

Vâng, tôi đang sử dụng NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld giá trị đã có để có được xung quanh này. Nó không phải là vấn đề lớn, tôi chỉ tự hỏi nếu có một cách dễ dàng hơn và 'được xây dựng' để làm điều này. Chúc mừng! –

+0

Tôi đã có chính xác những suy nghĩ tương tự, Niall. Thật tốt khi nghe xác nhận từ Rob rằng, thực sự, hệ thống KHÔNG gửi tin nhắn, ngay cả khi giá trị mà nó vừa đặt là như nhau. Nghĩ rằng, trong một số trường hợp, và ở đây tôi có nghĩa là hoàn toàn cho hiệu suất (trong trường hợp hiếm hoi có vấn đề) có thể tốt hơn để kiểm tra "kết thúc gửi" rằng nó là một giá trị không thay đổi (và do đó, đơn giản là không đặt nó) thay vì kiểm tra trên "kết thúc nhận" (ví dụ, nếu bạn có rất nhiều người nhận và bạn đang thực hiện một so sánh phức tạp, một chuỗi hoặc bất cứ điều gì). Cảm ơn Rob Napier lần nữa. – Fattie

2

Chỉ cần để tham khảo, để thêm logic này để setter (sử dụng nhãn hiệu thông báo thay đổi), bạn sẽ sử dụng:

- (void)setValue:(int)value 
{ 
    if (_value == value) return; 
    [self willChangeValueForKey:@"value"]; 
    _value = value; 
    [self didChangeValueForKey:@"value"]; 
} 

+ (BOOL)automaticallyNotifiesObserversOfValue { return NO; } 
+0

Đây là những gì tôi làm! Tài liệu được ghi ở đây: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html#//apple_ref/doc/uid/20002178-SW1 – Klaas

+0

Đây là những gì tôi làm, quá. Tốt hơn cho hiệu suất và bảo trì hơn so với kiểm tra lặp lại trên một số lượng lớn người nhận. –

Các vấn đề liên quan