2013-07-10 42 views
10

Tôi đang sử dụng KVO để quan sát các thay đổi trên NSManagedObject. NSManagedObject Tôi đang quan sát là một phần của bối cảnh NSManagedObject nằm trên hàng đợi chính.Thông báo KVO sau khi hợp nhấtChangesFromContextDidSaveNotification

Khi tôi cập nhật đối tượng này theo ngữ cảnh (loại hàng đợi đồng thời) và sau đó hợp nhất các thay đổi đã lưu vào ngữ cảnh hàng đợi chính của tôi (trong hợp nhấtChangesFromContextDidSaveNotification), thông báo KVO kích hoạt như mong đợi.

Tuy nhiên, tôi hy vọng rằng các thông báo sẽ chỉ kích hoạt cho các đường dẫn chính thực sự thay đổi và không phải cho tất cả các đường dẫn của NSManagedObject. Tôi nhận được thông báo KVO cho mọi rãnh khóa của đối tượng của tôi mặc dù chúng không thay đổi.

Đây có phải là do thiết kế hoặc tôi đang làm điều gì đó sai?

Không thể nhìn thấy bất cứ điều gì trong tài liệu táo ....

+0

Bạn xử lý thông báo như thế nào? Bạn nên xem NSUpdatedObjectsKey của từ điển userInfo thông báo. – random

+0

Tôi đã triển khai phương thức này: - (void) observValueForKeyPath: (NSString *) keyPath ofObject: (id) thay đổi đối tượng: (NSDictionary *) thay đổi ngữ cảnh: (void *) context; – aloo

+0

Bây giờ tôi có thể nhìn vào từ điển thay đổi và nhìn vào giá trị cũ để xem liệu giá trị của nó có thay đổi so với giá trị hiện tại hay không - nhưng tại sao tôi lại nhận được thông báo KVO ngay từ đầu nếu nsmanagedobject thậm chí không thay đổi cho keypath đã cho? – aloo

Trả lời

3

Nó không có giấy tờ nhưng quan sát hành vi trên cả OS X và iOS mà lưu được tính là một thay đổi cho toàn bộ NSManagedObject không chỉ các yếu tố khác nhau. Bạn có thể tìm thấy những càu nhàu về những hậu quả khác nhau của điều đó đối với các ràng buộc và những thứ tương tự xung quanh trang web này, trên openradar.appspot.com, v.v. Vấn đề đó cũng thể hiện với các tia lửa KVO rõ ràng là hoàn toàn không ngạc nhiên.

Cách đơn giản nhất để xử lý sự cố (tốt, đơn giản nhất sau khi 'chỉ hiển thị lại mọi thứ khi lưu' mà tôi thấy tùy chọn vượt qua đầu tiên cho đến khi ai đó than phiền) là lắng nghe thông báo chung chung, sau đó gọi -changedValues ​​trên mỗi đã cập nhật đối tượng để chọn ra những đối tượng bạn quan tâm trong việc kích hoạt cập nhật cụ thể.

Nếu điều đó vô ích đối với trường hợp sử dụng của bạn, bạn có thể tạo accessors tùy chỉnh (mogenerator là một trợ giúp lớn với điều này) cho các thuộc tính của bạn thu thập trên cờ thread chỉnh sửa cho tất cả các thuộc tính mà bạn quan tâm; và gửi thông báo đó sau khi lưu.

Ví dụ: giả sử chúng tôi có a professional sports team app được cập nhật liên tục với nguồn cấp dữ liệu JSON được phân tích cú pháp trong nền. Tất cả các thuộc tính hiển thị ảnh hưởng của các nhóm, trình phát, trò chơi, v.v. NSManagedObject khác nhau có trình truy cập tùy chỉnh đặt cờ trong cấu trúc {playerStatsChanged, teamStatsChanged, leagueRankingsChanged, yadayadayadaChanged} tương ứng với các trang trong ứng dụng sẽ cần hiển thị lại khi tìm nạp hiện tại -and-parse thread hoàn thành. Sau đó, khi nó được lưu, nó sẽ tắt thông báo chung 'cập nhật các màn hình này' với cấu trúc thiết lập cờ đó. Bạn có thể kết hợp các thông báo đường dẫn thay đổi cá nhân vào một mức độ cao hơn 'cập nhật màn hình này' loại logic ở đâu đó trong mọi trường hợp, phải không? Vâng, ở cấp độ setter tài sản là khá nhiều điểm phí thấp nhất bạn có thể làm điều đó tại, cho các trường hợp sử dụng hợp lý nhất. Chắc chắn đối với bất kỳ thiết kế cập nhật định kỳ nào được tải xuống như ứng dụng nhóm thể thao của chúng tôi tại đây.

+0

Cảm ơn phản hồi tuyệt vời này. Bất kỳ liên kết nào xác minh rằng đây là sự cố đã biết của một số người? Chỉ muốn chắc chắn rằng tôi không làm gì sai. Tôi sẽ đi xuống con đường kiểm tra thông báo KVO để xem liệu giá trị cũ có khác với giá trị mới không - nếu có, sau đó cập nhật giao diện người dùng. – aloo

+0

Xem ví dụ lỗi radar mở này - http://openradar.appspot.com/6624874 - KVO đang sử dụng của bạn trên đối tượng được lưu vào hiệu quả tương đương với Giải pháp của mình 3. –

+1

Ngoài ra, tài liệu về Tuân thủ KVO - http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/KeyValueObserving/Articles/KVOCompliance.html - tuyên bố rằng thông báo trên mọi setValue là mặc định trừ khi bạn viết mã cụ thể để kiểm tra các thay đổi. Có thể nhóm Core Data đã viết rằng cho mọi loại trường dữ liệu Core có thể, và gọi đó là bộ so sánh thích hợp cho mọi lĩnh vực của mọi đối tượng trên mỗi lần lưu, như cần thiết cho KVO trên lưu vào đối tượng để làm việc như bạn mong đợi? ... naah, không phải vậy. –

0

Bạn có thể ghi đè lên các thông báo thay đổi tự động với các thông báo hướng dẫn cho chỉ các phím bạn đã chọn. Kiểm tra tài liệu chi tiết here.

+0

Tôi không muốn mã hóa các phím mà tôi muốn nhận thông báo. Tôi muốn thông báo được gửi cho CHỈ các đường dẫn thực sự đã thay đổi sau khi hợp nhất. Hiện tại tôi đang nhận được thông báo cho các đường dẫn không thay đổi. – aloo

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