2011-08-08 22 views
5

hi :) Tôi có một tương tự phát hành như trong Working with the same NSManagedObjectContext in multiple tabs
nền:
My managedObjectContext (thêm MOC) được khởi tạo trong lớp appdelegate của tôi và thông qua Xuyên với nhiều tab bằng
myViewController.managedObjectContext = self.managedObjectContext; hoặc trong phương pháp init với self.managedObjectContext = pContext; luồng là: chế độ xem đầu tiên là danh sách các bộ sưu tập đơn giản. Các bộ sưu tập được tìm nạp với một NSFetchedResultsController (myViewController : UITableViewController<NSFetchedResultsControllerDelegate>). Bằng cách chọn một, bạn điều hướng sâu hơn, nhưng vẫn chuyển MOC này.
Trong bộ điều khiển tiếp theo (detailsViewController), tôi liệt kê một số mục của bộ sưu tập này những gì tôi có thể tương tác với (thiết lập thiết bị chuyển mạch chẳng hạn).
Tôi cũng có một editingObjectContext:
NSManagedObjectContext không làm mới một cách chính xác

// DetailsViewController.m 
NSManagedObjectContext* editingContext = [[NSManagedObjectContext alloc] init]; 
[editingContext setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]]; 
self.editingObjectContext = editingContext; 

Bây giờ vấn đề của tôi: bởi vì quan điểm của tôi phải xoay, Tôi đang sử dụng các trick folowing:

// DetailsViewController.m 
DetailsView *localAct = [[DetailsView alloc] initWithManagedObjectContext:managedObjectContext ... ] 
DetailsView *localSen = [[DetailsView alloc] initWithManagedObjectContext:managedObjectContext ... ] 

UITableView *localContainerView = [[UITableView alloc] init]; 
self.containerView = localContainerView; 
[localContainerView release]; 
//[...] 
[containerView addSubview:actuatorView]; 
self.tableView = containerView; 

hơn nữa tôi có một nút để quản lý mặt hàng này (trong số đó sẽ được hiển thị và không được hiển thị). Nút này chỉ tải lại bảng với hàm fetchResult mới.

// DetailsView.m 
- (void) manageItems{ 
managing = !managing; 
[viewController setIsManaging:managing]; // parent 
self.fetchedResultsController = nil; 

NSError *error = nil; 
[[self fetchedResultsController] performFetch:&error]; 

[self reloadData]; 
[self updateBarButton]; 
} 

Phương pháp đặt các mục vào bối cảnh trông như vậy:

// DetailsViewController.m 
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
// init + create predicate 
NSSet* set = [sen filteredSetUsingPredicate:predicate]; 
if([set count] > 0) 
{ 
    for(Act* act in set) 
    { 
     [editingObjectContext deleteObject:act]; 
    } 
} 
else 
{ 
    Act* act = [NSEntityDescription insertNewObjectForEntityForName:@"Act" inManagedObjectContext:editingObjectContext]; 

    // do things 
} 
NSError *error = nil; 
[[detailView fetchedResultsController] performFetch:&error]; 

[self.containerView reloadData]; 
[detailView reloadData]; 
} 

nhưng sau khi tôi chọn các mục trong giao diện quản lý và nhấp tiết kiệm (manageItems), quan điểm không hiển thị chúng :/tôi phải chuyển đổi tab hoặc điều hướng trong một bộ điều khiển khác (cha mẹ hoặc sâu hơn) để hiện thực hóa nó. phương pháp viewWillAppear tôi:

// DetailsViewController.m 
- (void)viewWillAppear:(BOOL)animated 
{ 
[super viewWillAppear:animated]; 
DetailsView *detailView = se ? senView : actView; 
// [do uninteresting stuff] 
[detailView.fetchedResultsController performFetch:nil]; 
[self.tableView reloadData]; 
// [do uninteresting stuff] 
} 

và viewWillDisapper gọi

- (void)saveChanges 
{ 
if(![editingObjectContext hasChanges]) 
    return; 

// send save-command to server 
} 

Trong một earliert Verison nơi chỉ có 1 cái nhìn nó làm việc và tôi đã không thay đổi thực sự nhiều ...:/vì vậy tôi don không hiểu tại sao MOC lại hành động như vậy. Phần "manageItems" gần như bằng nhau, nó chỉ ở mức sâu hơn trong phiên bản mới (trong DetailsView thay vì bộ điều khiển) ...

nếu ai đó có thể cho tôi biết tôi có thể thử gì (luôn lưu vào máy chủ khi chuyển đổi giữa quản lý và bình thường không phải là một giải pháp vì sự chậm trễ trong phản hồi từ máy chủ là cao cho việc làm mới, vì vậy tôi có ít hơn để lật chế độ xem. Ngoài ra làm mới chế độ xem với self.tableView/detailView/self.containerView refresh mang lại kết quả tương tự: /).

và sự cố thứ hai: Tôi không thể gọi phương thức "editingObjectContext save:" sau khi gửi tới máy chủ, vì nó ném lỗi và không lưu vào cơ sở dữ liệu cục bộ.

Lỗi trong handleChangeResponse: "Các hoạt động không thể hoàn tất (lỗi Cocoa 133020.)" Lỗi miền = Mã NSCocoaErrorDomain = 133.020 UserInfo = 0x4d8bb90 {conflictList = ( "NSMergeConflict (0x5a2fac0) cho NSManagedObject (0x5a46a80) với objectID '0x5a46420' với oldVersion = 7 và newVersion = 8 và đối tượng cũ snapshot = {\ n iconName = noicon; \ n [...]; \ n} và hàng được lưu trong bộ nhớ cache mới = {\ n iconName = noicon; \ n [...] \ N}" )}

nếu bạn có thắc mắc hoặc cần một số mã khác (ví dụ: các phiên bản cũ hơn) sau đó chỉ cần hỏi;)

nhờ dự đoán :)

+0

okay, tôi đã tìm thấy phiên bản làm việc với flipview ... đã sao chép mã vào mã mới, nhưng vẫn cùng một vấn đề ...:/ '- (void) manageItems/* DetailsViewController */ { \t DetailsView * detailView = isSen? senView: actView; \t [detailView manageItems]; } ' --- ' - (void) manageItems // DetailsView { \t quản lý =! Quản lý; \t [viewController setIsManaging: manage];/* parent */ \t self.fetchedResultsController = nil; \t Lỗi NSError * = nil; \t [[self fetchedResultsController] performFetch: & error]; \t [viewController.containerView reloadData]; \t [tự cập nhậtBarButton]; } ' – geo

Trả lời

6

Dường như tôi có giải pháp! Kể từ IOS 5.0 có một phương pháp mới cho NSManagedObjectContext:

[managedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; 

Tìm thấy trên http://pauloliveira.net/tech/core-data-merging-conflicts
Thiết thuộc tính này để Bộ Xây dựng cấp cao nhất (trong trường hợp của tôi trong appdelegate) và không có nơi nào khác! xóa các vấn đề kết hợp của tôi;)

+0

setMergePolicy: khả dụng từ iOS 3.0 – rowwingman

0

tôi thấy lý do tại sao nó không hoạt động ... quên tất cả những gì tôi đã viết ở trên ... vấn đề là trong fetchrequest - cụ thể: trong vị ngữ ... trong các phiên bản trước tôi đã sử dụng

[NSComparisonPredicate predicateWithLeftExpression: ...] 

trong thực tế ver sion tôi sử dụng

NSString * predicateFormat = [NSString stringWithFormat: ...]; 
NSPredicate* predicate = [NSPredicate predicateWithFormat:predicateFormat]; 

vì tôi đã phải mở rộng số lượng các tùy chọn và cũng thay đổi nội dung theo yêu cầu riêng của mình bởi vì nó làm cho các vấn đề trong ngữ (so sánh một đối tượng đầy đủ (của lớp MOC, chiết xuất từ ​​cơ sở dữ liệu) với một thực thể đã không làm việc, vì vậy tôi quản lý workaround trong DetailsViewController và đã không cuộn lại bản cập nhật của tôi ở nơi này: /).
Không bao giờ nghĩ lãng phí quá nhiều thời gian cho vấn đề này>. < nhưng không sao, miễn là nó được giải quyết: D

Tôi sẽ kiểm tra xem vấn đề thứ hai (với vấn đề tiết kiệm) vẫn tồn tại. Nếu không, tôi sẽ cập nhật bài đăng của mình, nếu không chủ đề này không bị đóng:/

0

Điều này có thể là do bối cảnh quản lý trong việc sử dụng đối tượng mà bạn nhận được điều này. Loại bỏ tất cả NSManagebobject tại thời điểm bạn đăng xuất hoặc di chuyển trở lại. nói kết thúc bằng ứng dụng. Có vẻ như thế này ...

[NSManagebobjectcontext setManagedObjectsDictionary:[NSMutableDictionary dictionary]]; 
Các vấn đề liên quan