13

Tôi có một ứng dụng iPhone có MainWindow.xib đang nắm giữ UITabBarController, lần lượt có UINavigationController và một lớp con UIViewController tùy chỉnh trong mảng ViewControllers của nó. Bộ điều khiển xem gốc cho UINavigationController và bộ điều khiển xem tùy chỉnh đều được nạp từ các tệp xib khác.Cách chia sẻ ManagedObjectContext khi sử dụng UITabBarController

Ứng dụng sử dụng dữ liệu cốt lõi, ngăn xếp được khởi tạo trong ứng dụng đại biểu (theo the convention).

Các đại biểu ứng dụng thêm các UITabBarController vào cửa sổ:

- (void)applicationDidFinishLaunching:(UIApplication *)application {   
    // Configure and show the window 
    [window addSubview:[tabBarController view]]; 
    [window makeKeyAndVisible]; 
} 

Tôi nhận ra rằng tôi cần phải tuyên truyền một con trỏ đến ManagedObjectContext tạo ra trong các đại biểu ứng dụng, nhưng tôi không biết làm thế nào để tiếp tục (thậm chí đọc tất cả các bài bình luận tốt về chủ đề herehere):

  • tôi tuyên truyền các ManagedObjectContext đến UITabBarController và từ đó vào các bộ điều khiển xem cá nhân và nếu như vậy, làm thế nào?
  • Hoặc tôi có truyền trực tiếp ManagedObjectContext tới bộ điều khiển chế độ xem gốc của UINavigationController và đến trình điều khiển chế độ xem tùy chỉnh không và tôi sẽ làm như thế nào?

Tôi đoán tôi không hiểu đủ về cách làm việc với UITabBarController.

Trả lời

14

Lý tưởng nhất là bạn muốn chuyển số NSManagedObjectContext, NSFetchedResultsController hoặc NSManagedObject "xuống" có liên quan vào số UIViewController. Điều này cho phép "cha mẹ" để kiểm soát "đứa trẻ" và xác định những gì đứa trẻ cần phải có. Điều này tạo ra một thiết kế kết hợp lỏng lẻo hơn và cho phép bạn dễ dàng sắp xếp lại các trường hợp UIViewController nếu cần.Nó cũng giúp bạn dễ dàng sử dụng lại một số UIViewController.

Trong thiết kế chế độ xem tab, không có gì khác biệt. AppDelegate của bạn chuyển số NSManagedObjectContext cho bất kỳ ai chịu trách nhiệm tạo các trường hợp UIViewController ban đầu đi vào UITabBarController. Đổi lại, người sáng tạo chuyển các thông tin có liên quan (NSManagedObject, NSFetchedResultsController và/hoặc NSManagedObject trường hợp) vào các trường hợp UIViewController vì nó đang xây dựng chúng.

+4

Liên kết ở trên không hoạt động ... – TraderJoeChicago

+0

Có, họ đã gỡ xuống các bài báo, tôi sẽ sớm đăng lại trên CIMGF. –

+0

Sẽ hữu ích khi đăng câu trả lời đơn giản cho thanh tabbar, thay vì liên kết. Liên kết đi cũ. – lostintranslation

-1

Một giải pháp thẳng về phía trước hơn là làm cho ManagedObjectContext tài sản công cộng đại biểu ứng dụng của bạn để bất cứ nơi nào bạn cần truy cập vào nó, bạn sẽ làm như sau:

[[[UIApplication sharedApplication] delegate] sharedManagedObjectContext]; 

giả định rằng sharedManagedObjectContext là tên tài sản.

+0

Điều đó có thể làm việc, và tôi sẽ thử nó, nhưng tôi vẫn tò mò làm thế nào để làm điều đó sau khi mẫu thiết kế của Apple đưa ra trong tài liệu hướng dẫn của nó (xem liên kết trong câu hỏi của tôi). Cảm ơn câu trả lời trong mọi trường hợp. – mvexel

+0

Điều đó thực sự phụ thuộc vào kiến ​​trúc của ứng dụng của bạn. Bạn không phải thiết lập NSManagedObjectContext trong ủy nhiệm ứng dụng của bạn, đặc biệt nếu việc bạn sử dụng nó bị giới hạn trong một bộ điều khiển khung nhìn, trong trường hợp này bạn đặt nó trong bộ điều khiển xem đó. Nếu tôi có thể đọc nó đúng, Apple đề nghị bạn khởi tạo bộ điều khiển xem của bạn thông qua NSManagedObjectContext được chia sẻ bằng cách sử dụng phương thức custom -initWithManagedObjectContext: (bạn viết một cái gì đó như thế này), nhưng cách tiếp cận này sẽ không dễ dàng làm việc cho một hệ thống phân cấp khung nhìn phức tạp. – Costique

+3

Không, làm * không * làm điều này. Không có ví dụ nào của Apple theo mẫu này; nó không được khuyến khích (xem http://developer.apple.com/mac/library/documentation/DataManagement/Conceptual/CoreDataSnippets/Articles/stack.html#//apple_ref/doc/uid/TP40008283-SW1). Bạn nên vượt qua một ngữ cảnh hoặc một đối tượng được quản lý từ một bộ điều khiển khung nhìn đến điều khiển tiếp theo. – mmalc

1

Tốt, tôi nhìn lâu dài và khó khăn tại đơn CoreDataBooks mẫu và đã làm điều đó như thế này:

  • IBOutlets Created đến RootViewController (bộ điều khiển xem đầu UINavigationController) và MapViewController (bộ điều khiển giao diện tùy chỉnh) trong ứng dụng đại biểu.
  • kết nối các cửa hàng để các bộ điều khiển xem trong MainWindow.xib
  • Added đoạn mã sau để applicationDidFinishLaunching:

    // pass the managed object context to the view controllers 
    RootViewController *rootViewController = (RootViewController *)[navigationController topViewController]; 
    rootViewController.managedObjectContext = self.managedObjectContext; 
    
    mapViewController.managedObjectContext = self.managedObjectContext; 
    

Và bây giờ nó hoạt động như một nét duyên dáng.

+0

Bạn có thể giải thích chi tiết những gì bạn đã làm, xin vui lòng. – zkaje

+0

@zkaje - phần nào không rõ ràng? – mvexel

+0

ngày nay tất cả đều rõ ràng, thực sự tôi không nhớ những gì tôi đã bỏ lỡ tại thời điểm đó và tại sao không thể hiểu nó, anyway thx trả lời :) – zkaje

11

Nếu bạn muốn sử dụng phương pháp dependency injection để vượt qua bối cảnh đối tượng được quản lý với một bộ điều khiển thanh tab, một giải pháp mạnh mẽ hơn sẽ là để lặp trên tất cả các bộ điều khiển xem trong applicationDidFinishLaunching:

for (id vc in tabBarController.viewControllers) { 
    [vc setManagedObjectContext:self.managedObjectContext]; 
} 
0

Sử dụng Xcode 3.2.1 và nhắm mục tiêu 3.1.3 Tôi đã có vấn đề bất tận với cách tiếp cận

rootViewController.managedObjectContext = self.managedObjectContext; 

rằng mvexcel mô tả (và rằng nó được sử dụng tất cả các ứng dụng trong suốt mẫu), tuy nhiên sử dụng chính xác phương pháp tiếp cận tương tự nhưng thực hiện như sau:

[rootViewController setManagedObjectContext:self.managedObjectContext]; 

hoạt động hoàn hảo.

Tôi cũng gặp nhiều vấn đề với trình tạo giao diện không đồng bộ hóa chính xác với Xcode và do đó không thể kết nối với các cửa hàng để vượt qua ngữ cảnh. Hy vọng rằng bản phát hành tiếp theo sẽ khắc phục tất cả điều này.

0

Xin chào Tôi biết đây là một chủ đề cũ, nhưng tôi cũng gặp sự cố khi tìm cách tốt nhất để xử lý chia sẻ MOC giữa TABS - mong muốn liên kết của Marcus Zarra về chủ đề vẫn hoạt động. Marcus hoàn toàn đá, làm cho dữ liệu mát mẻ.

Đây là giải pháp hiện tại của tôi trong ứng dụng didFinishLaunching:

NSArray *viewControllers = [tabBarController viewControllers]; 
    NSManagedObjectContext *context = self.managedObjectContext; 
    for (id viewController in viewControllers) { 
     [viewController setManagedObjectContext:context]; 

} 
1

Tôi đã chạy vào vấn đề này cùng, tôi sẽ chia sẻ giải pháp của tôi.

Trước tiên, bạn cần tham chiếu đến Bộ điều khiển Nav trong Thanh tab trong tệp nib, đảm bảo bạn kết nối nó.

IBOutlet UINavigationController *navigationController; 

Sau đó, có được điều khiển theo khuyến cáo trong các tài liệu hỗ trợ và gửi nó trở thành managedObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController]; 
saved.managedObjectContext = self.managedObjectContext; 

Alex (từ bài khác) là đúng, "Thông thường bạn nên tránh xa nhận đối tượng chia sẻ từ ứng dụng đại biểu, nó làm cho nó hoạt động quá nhiều như một biến toàn cầu, và có một mớ hỗn độn của các vấn đề liên kết với nó."

0

Trong trường hợp của tôi, tôi có một rootViewController và sau đó tôi có một TabBarController, vì vậy trong segue khi tôi chuẩn bị tabBarController tôi đặt đại biểu của nó:

if ([[segue identifier]isEqualToString:@"initialTabBar"]) [(UITabBarController *)[segue destinationViewController] setDelegate:self]; }`

tôi thêm các giao thức để các tabBarDelegate trong RootViewController của tôi (tôi gọi MainViewController):

@interface MainViewController()<UITabBarControllerDelegate>

Và cuối cùng trong phương pháp đại biểu:

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{

tôi thiết lập thuộc tính, nhưng trước đây tôi chắc chắn rằng viewController có tính chất chính xác:

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{ 

    if ([viewController respondsToSelector:@selector(managedContextObject)]) { 
    [viewController setValue:self.managedObjectContext forKey:@"managedContextObject"]; 
    } 
} 

Vì vậy, nếu bất kỳ việc sử dụng viewController's tab đừng các managedContextObject đơn giản Tôi không tạo thuộc tính trong .h

Tôi hy vọng điều này sẽ hữu ích.

0

Chỉ cần lặp qua từng chế độ xemController, kiểm tra xem nó có thuộc tính managedObjectContext và sau đó đặt nó nếu có. Đây là cách sạch nhất tôi có thể tìm thấy để làm điều đó.

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController; 
for (id viewController in [tabBarController viewControllers]) { 
    if ([viewController respondsToSelector:@selector(setManagedObjectContext:)]) { 
     [viewController setManagedObjectContext:self.managedObjectContext]; 
    } 
} 
Các vấn đề liên quan