2009-08-09 34 views
5

Trong ca cao, addObserver:forKeyPath:options:context: giữ lại "không phải người nhận, cũng không phải máy chủ an toàn". Do đó tôi cho rằng việc quan sát bản thân được phép; có nghĩa là, nó hoàn toàn hợp lệ để làm điều gì đó nhưQuan sát tự trong Cocoa

[self addObserver:self forKeyPath...]

Chừng nào bạn nhớ để unregister self như một người quan sát là điều đầu tiên trong dealloc.

Giả định này có đúng không?

Trả lời

12

Có, thực sự không có lý do gì khiến bạn không thể quan sát bản thân. Nhưng như bạn đã nói, giống như bất kỳ quan sát KVO nào, hãy chắc chắn để loại bỏ mình như một người quan sát trước khi bị xử lý.

Để ghi lại, một cách thay thế để thực hiện việc này nếu bạn chỉ nói về một khóa đơn giản là viết trình tùy chỉnh và thực thi bất kỳ mã nào bạn cần trong trình thiết lập. Phong cách này làm cho nó rõ ràng hơn một chút những gì các hiệu ứng đầy đủ của gọi setter được. Cách KVO là một chút linh hoạt hơn mặc dù, và làm việc với các đường dẫn chính có chứa nhiều thành phần.

1

Tôi làm những gì Brian Webster nói. Dưới đây là ví dụ:

//.h 
... 
@property(readwrite, retain, setter=setMyPropertySynth:) id myProperty; 
-(void)setMyProperty:(id)newValue; 
.... 


//.m 
... 
@synthesize myProperty; 

-(void)setMyProperty:(id)newValue 
{ 
    //add code here 

    [self setMyPropertySynth:newValue]; 

    //add more code here 
} 
... 
+0

Đây không phải là một ý tưởng hay. Người ta thường hy vọng rằng 'obj.foo = bar;' phải tương đương với '[obj setFoo: bar];' và straying từ mẫu này sẽ gây nhầm lẫn cho người khác đang đọc/duy trì mã của bạn – rpetrich

+0

@rpetrich Tôi đồng ý rằng điều này không một ý tưởng hay (tôi đã viết câu trả lời đó hơn 18 tháng trước), nhưng vì một lý do khác. Tôi sẽ không còn sử dụng '@ synthesize' nữa; Bây giờ tôi sẽ viết toàn bộ getter và setter. Các gánh nặng thêm của một vài dòng phụ trội hơn chi phí tinh thần sau các cuộc gọi phương thức bổ sung (tôi vẫn còn sử dụng '@ property'). Tôi không đồng ý rằng các tác dụng phụ ở những người định cư (hoặc getters) vốn đã xấu. Họ nên tránh nếu có thể. Ví dụ, thiết lập 'hypotheticalQueryObject.maxResults = 4;' có thể kích hoạt một tìm kiếm hợp pháp khác. –

+0

@rpetrich Điều đó thực sự được đảm bảo. 'obj.foo = bar;' luôn sử dụng bất kỳ việc thực thi 'setFoo:' nào được cung cấp (ngay cả khi bạn đã ghi đè một cái tổng hợp). –

-1

Không xóa người quan sát trong -dealloc. Tại sao? Bởi vì khi bạn bật máy thu gom rác, mọi thứ sẽ ngừng hoạt động; -dealloc không bao giờ được gọi. Bạn chỉ nên sử dụng các phương pháp -dealloc-finalize cho mã dọn dẹp liên quan đến bộ nhớ.

+0

Điểm tốt; nhưng, tôi nên sử dụng cái gì? –

+0

Chỉ cần thiết lập nó như là một phần của vòng đời của đối tượng. Nếu thứ tạo ra nó cho nó biết cái gì cần quan sát, và khi nào dừng quan sát nó, bạn đang suy diễn các phụ thuộc_ làm cho đối tượng của bạn dễ sử dụng và thử nghiệm hơn. –

+3

... nhưng dễ sử dụng hơn nhiều và làm suy yếu quản lý bộ nhớ Cocoa. Nếu mọi người sáng tạo cũng phải biết rằng đối tượng được tạo phải quan sát như vậy (đặc biệt nếu đó là chính nó), chúng tôi đã chuyển thông tin cá nhân vào người gọi, điều đó thật tệ. Tệ hơn nữa, nếu tôi cần một phương pháp "tiêu diệt bạn ngay bây giờ" để hoàn tác sự quan sát này, thì toàn bộ điểm GC đã đi ra ngoài cửa sổ. Giải pháp tốt nhất mà chúng tôi có là sao chép các phần quản lý không phải bộ nhớ vào dealloc và hoàn thiện (có thể nâng lên một thói quen chia sẻ). Điều này bao gồm cả NSNotificationCenter removeObserver. –

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