22

Cacao/ứng dụng của tôi có một bối cảnh đối tượng được quản lý trên luồng chính. Khi tôi cần cập nhật dữ liệu của tôi chương trình của tôi sẽ:Dữ liệu chính hợp nhất hai bối cảnh đối tượng được quản lý

  1. Bắt đầu một chủ đề mới
  2. Nhận dữ liệu mới từ một máy chủ
  3. Tạo một Managed Object Bối cảnh mới
  4. Gửi thông báo tới các chủ đề chính để hợp nhất hai ngữ cảnh

Đây là chức năng nhận thông báo trên sợi chính

- (void)loadManagedObjectFromNotification:(NSNotification *)saveNotification 
{ 
    if ([NSThread isMainThread]) { 
     [self.managedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification]; 
    } else { 
     [self performSelectorOnMainThread:@selector(loadManagedObjectFromNotification:) withObject:saveNotification waitUntilDone:YES];  
    } 
} 

Tôi không nhận được bất kỳ lỗi nào. Vấn đề của tôi là kết quả hợp nhất, nó thực sự nối các đối tượng được quản lý từ cả hai ngữ cảnh.

Thực thể của tôi là danh sách thuộc tính và mối quan hệ thực sự đơn giản.

Có thể hợp nhất cần một số hướng dẫn để hiểu khi nào một đối tượng được quản lý cập nhật KHÔNG PHẢI là một phiên bản mới, nhưng là phiên bản được chỉnh sửa của phiên bản đầu tiên. Tôi tưởng tượng rằng một nơi nào đó tôi cần xác định một cách để nhận diện một thực thể, (một thuộc tính ví dụ có thể hoạt động như một ID) và một cái gì đó giống như một chính sách hợp nhất (nếu 2 đối tượng được quản lý đại diện cho cùng một đối tượng, lấy một đối tượng với lastModificationDate gần đây hơn).

Tôi chỉ cần hiểu cách hợp nhất chính xác 2 ngữ cảnh để có một bản cập nhật duy nhất cho từng đối tượng.

CẬP NHẬT 1

Hiện tại vấn đề đã rõ ràng đối với tôi. Ngữ cảnh 2 có sự khác biệt lớn: ObjectID. Trong khi ngữ cảnh trên luồng chính tìm nạp ManagedObjects với điều phối viên Persistent Store, luồng thứ hai tạo ra các đối tượng đó bằng cách tìm nạp một URL từ xa. Ngay cả khi các đối tượng có cùng nội dung, chúng sẽ có 2 objectID khác nhau.

Đối tượng của tôi đã có một định danh duy nhất, tôi có thể sử dụng setObjectId để đặt giá trị này. (Tài liệu của Apple cho biết đây KHÔNG phải là ý hay).

+1

Rõ ràng là các ID đối tượng khác nhau, vì bạn đang tạo các đối tượng thay vì tìm nạp chúng từ cửa hàng và cập nhật chúng. Đó là lý do tại sao tôi nói trong câu trả lời của tôi rằng bạn không cần bất cứ điều gì khác để kết hợp các đối tượng. Dù sao, cách thích hợp để xử lý tình huống này là sử dụng ID đối tượng được quản lý. Vì ID đối tượng được quản lý là chuỗi an toàn, bạn có thể chuyển chúng từ chuỗi chính của bạn đến chuỗi khác, sau đó sử dụng existingObjectWithID: error: để truy xuất đối tượng được liên kết với ID cụ thể, cập nhật và lưu ngữ cảnh. Bây giờ hợp nhất sẽ hoạt động như bạn mong đợi. –

+0

Ngoài ra, nếu bạn không biết trước ID đối tượng được quản lý phải được truyền giữa các luồng, thì trong chủ đề khác, bạn chỉ cần tìm nạp các đối tượng bằng cách sử dụng vị từ để truy xuất các đối tượng tương ứng với các đối tượng được truy xuất từ ​​máy chủ, sau đó bạn cập nhật và lưu ngữ cảnh. –

+0

Chính xác! Vấn đề là objectIds. Bây giờ mỗi khi tôi thực hiện tìm nạp và tôi cần phải cập nhật một đối tượng hiện có, tôi lấy đối tượng từ cửa hàng và cập nhật nó. – Giuseppe

Trả lời

32

Đây là những gì bạn cần làm để hợp nhất chính xác các ngữ cảnh. Trước tiên, bạn không cần thông báo của riêng bạn.Thực hiện tiết kiệm hoạt động trên một bối cảnh tự động chuyển tiếp các thông báo sau đây để các quan sát viên đã đăng ký:

NSManagedObjectContextDidSaveNotification 

Vì vậy, tất cả các bạn cần làm là:

1) trong chủ đề chính của bạn, có thể là trong phương pháp viewDidLoad, đăng ký thông báo này:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(contextDidSave:) 
              name:NSManagedObjectContextDidSaveNotification 
              object:nil]; 

2) thực hiện phương pháp contextDidSave: trong chủ đề chính của bạn như sau:

- (void)contextDidSave:(NSNotification *)notification 
{ 

    SEL selector = @selector(mergeChangesFromContextDidSaveNotification:); 
    [managedObjectContext performSelectorOnMainThread:selector withObject:notification waitUntilDone:YES]; 

} 

3) trong phương pháp dealloc bạn thêm dòng sau:

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

4) tạo ra một bối cảnh mới trong chủ đề khác của bạn sử dụng một cái gì đó giống như phương pháp sau đây:

- (NSManagedObjectContext*)createNewManagedObjectContext 
{ 

    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init]; 
    [moc setPersistentStoreCoordinator:[self persistentStoreCoordinator]]; 
    [moc setUndoManager:nil]; 
    return [moc autorelease]; 
} 

5) sau khi nhận được dữ liệu mới, cách thích hợp để xử lý tình huống này là sử dụng ID đối tượng được quản lý. Vì ID đối tượng được quản lý là chuỗi an toàn, bạn có thể chuyển chúng từ chuỗi chính của bạn đến chuỗi khác, sau đó sử dụng existingObjectWithID:error: để truy xuất đối tượng được liên kết với ID cụ thể, cập nhật ID và lưu ngữ cảnh. Bây giờ hợp nhất sẽ hoạt động như bạn mong đợi. Ngoài ra, nếu bạn không biết trước các ID đối tượng được quản lý phải được truyền giữa các luồng, thì trong chủ đề khác của bạn, bạn chỉ cần tìm nạp các đối tượng bằng cách sử dụng vị từ để lấy các đối tượng tương ứng với các đối tượng được lấy ra từ máy chủ, sau đó bạn cập nhật chúng và lưu ngữ cảnh.

+0

Điều này hoàn toàn giống với việc triển khai của tôi. Sự cố của tôi là sự hợp nhất. Khi tôi gọi [self.managedObjectTiếp hợp ngữThay đổiFromContextDidSaveNotification: saveNotification]; Nó nên hợp nhất ManagedObjects của tôi, nhưng nó chỉ làm một nối. – Giuseppe

+1

Thật khó để nói điều gì sai với việc triển khai của bạn mà không thấy tất cả mã nguồn có liên quan. Bạn có chắc là bạn đang lưu dữ liệu trong ngữ cảnh của chủ đề khác không? Tiết kiệm được yêu cầu (bởi vì một phép toán hợp nhất so sánh các đối tượng trong bộ nhớ so với các đối tượng lưu trữ), nhưng bạn không đề cập đến điều này trong câu hỏi của bạn. Giới thiệu về chính sách hợp nhất. chắc chắn bạn có thể đặt một trên mỗi bối cảnh nếu một mặc định không phù hợp với nhu cầu của bạn. Một lần nữa, không có chi tiết bổ sung khó mà nói. –

+0

Câu trả lời này là lời giải thích thích hợp duy nhất tôi tìm thấy trên mạng. –

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