6

Tôi có một ứng dụng iPad có UITableViewController triển khai NSFetchedResultsControllerDelegate. (Chủ yếu là sử dụng CoreDataTableViewControllercode từ các lớp học Stanford iOS.)Cách thiết lập KVO trên Bộ sưu tập (NSArray hoặc NSSet) của NSManagedObjects

Tôi có một đối tượng mô hình thứ cấp (self.locations) mà là một mảng của Location đối tượng mà là một lớp con của NSManagedObjects. Mảng này điều khiển nội dung của UISegmentedControl để lọc fetchedResultsContoller chính của tôi.

Có thể sửa đổi nội dung của self.locations qua cửa sổ bật lên. Tôi muốn thiết lập một số loại quan sát để UITableViewController chính của tôi có thể xem những thay đổi trong các đối tượng được lưu trữ trong self.locations và tải lại UISegmentedControl nếu cần thiết.

Điều này cũng có thể dẫn đến tải lại dữ liệu chính trong bảng, vì vậy tôi muốn cẩn thận để không tải lại trên mọi sửa đổi nhỏ.

Tôi nghĩ rằng tôi hiểu làm thế nào để thiết lập KVO trên một đơn NSManagedObject nhưng tôi không chắc chắn làm thế nào để làm điều đó trên đối tượng chứa trong một mảng. Tôi hiểu rằng tôi có thể sử dụng NSFetchedResultsController khác, nhưng đối tượng self.locations của tôi không có ổ đĩa UITableView thứ hai, vì vậy tôi không chắc nó có ý nghĩa hay không.

Trả lời

10

Khá thẳng về phía trước để quan sát mối quan hệ một-nhiều nếu tất cả những gì bạn muốn biết nếu các đối tượng được thêm vào, xóa, thay thế hoặc sắp xếp lại. Trong thực tế, nó được thực hiện chính xác theo cùng một cách như với một đối tượng bình thường:

[self addObserver:self 
     forKeyPath:@"locations" 
      options:0 
      context:NULL]; 

Sau đó, thực hiện những điều sau đây để nhận thông báo (sao chép một phần từ tài liệu của Apple):

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 

    if ([keyPath isEqual:@"locations"]) { 
     // Your custom code here. 
    } 

    // Be sure to call the superclass's implementation *if it implements it*. 
    [super observeValueForKeyPath:keyPath 
         ofObject:object 
          change:change 
          context:context]; 
} 

Đừng quên dừng lại quan sát tại một số điểm:

[self removeObserver:self forKeyPath:@"locations"]; 

Và, mặc dù bạn không hỏi, nếu bạn muốn biết nếu một trong các đối tượng chứa trong rel ationship có thay đổi (và không chỉ NSSet mà bạn đang xem ở đây) thì bạn phải quan sát các đối tượng riêng lẻ.

EDIT

mỗi nhận xét của bạn, bạn muốn quan sát các đối tượng cá nhân. Điều này là khá thẳng chuyển tiếp cho các đối tượng "bình thường", nhưng một đối tượng quản lý có làm việc nhiều hơn một chút bởi vì bạn phải quan sát các phím cá nhân trong đối tượng, trong đó sẽ giống như thế này:

- (void)observeManagedObject:(NSManagedObject *)myObject { 
    NSArray *myObjectKeys = [[[myObject entity] attributesByName] allKeys]; 
    for (NSString *key in myObjectKeys) { 
     [myObject addObserver:self 
        forKeyPath:key 
         options:0 
         context:nil]; 
    } 
} 

Và sau đó bạn quan sát tất cả các NSManagedObject trong mảng như sau:

for (NSManagedObject *object in myArray) { 
    [self observeManagedObject:object]; 
} 

Làm ngược lại để dừng quan sát các phím trên đối tượng được quản lý!

+1

Cảm ơn @Inafziger! Điều đó giúp ích rất nhiều. – DeepFriedTwinkie