2009-08-12 36 views
67

Trong Mẫu dữ liệu lõi iPhone, Apple đặt Ngăn xếp dữ liệu cốt lõi trong App Delegate.Nơi đặt "Ngăn xếp dữ liệu cốt lõi" trong ứng dụng Cocoa/Cocoa Touch

Tuy nhiên, độ nghiêng ban đầu của tôi là di chuyển mã này vào lớp riêng của mình mà trách nhiệm của họ là xử lý việc quản lý Ngăn xếp dữ liệu cốt lõi.

Bạn thường đóng gói chức năng này trong lớp học của riêng mình hay bạn để nó trong App Delegate?

Trả lời

39

Tóm tắt: Không cần để tạo ra một singleton để quản lý dữ liệu cốt lõi chồng; thực sự làm như vậy có khả năng phản tác dụng.

Ngăn xếp dữ liệu cốt lõi sẽ do đại biểu ứng dụng tạo ra. Quan trọng hơn, tuy nhiên, như tất cả các ví dụ hiển thị, ngăn xếp (chủ yếu là bối cảnh đối tượng được quản lý) là không phải được truy xuất trực tiếp từ ngăn xếp (*). Thay vào đó, ngữ cảnh được chuyển đến bộ điều khiển xem đầu tiên, và từ chúng trên một ngữ cảnh hoặc một đối tượng được quản lý được truyền từ một bộ điều khiển xem sang bộ điều khiển xem tiếp theo (như được mô tả trong Accessing the Core Data Stack). Điều này theo mô hình cơ bản cho iPhone tất cả các ứng dụng: bạn chuyển dữ liệu hoặc một bộ điều khiển mô hình từ một bộ điều khiển xem sang bộ điều khiển xem tiếp theo.

Vai trò tiêu biểu của singleton như được mô tả ở đây là bộ điều khiển mô hình. Với Core Data, bối cảnh đối tượng được quản lý đã là một bộ điều khiển mô hình. Nó cũng cung cấp cho bạn khả năng truy cập các phần khác của ngăn xếp nếu cần. Hơn nữa, trong một số trường hợp (như được mô tả trong tài liệu), bạn có thể muốn sử dụng một ngữ cảnh khác để thực hiện một bộ hành động riêng biệt. Đơn vị tiền tệ thích hợp cho một bộ điều khiển khung nhìn do đó thường là một bối cảnh đối tượng được quản lý, nếu không một đối tượng được quản lý. Sử dụng và truyền một đối tượng đơn lẻ quản lý một ngăn xếp (và từ đó bạn lấy một ngữ cảnh) thường giới thiệu tốt nhất một mức độ không cần thiết của sự hướng dẫn, và lúc tồi tệ nhất giới thiệu độ cứng ứng dụng không cần thiết.

(*) Không dụ lấy bối cảnh sử dụng:

[[UIApplication delegate] managedObjectContext]; 
+2

Không sử dụng tiêm phụ thuộc chắc chắn là một thiết kế tồi tệ khi tôi lần đầu tiên bắt đầu sử dụng Dữ liệu cốt lõi. Gần đây, tôi có cách tiếp cận tương tự như bạn đã vạch ra. Sự khác biệt chính là tôi đã đặt Mã ngăn xếp dữ liệu cốt lõi trong một danh mục trên Ngữ cảnh NSManagedObject, nếu chỉ để tách biệt mã ngăn xếp lõi dữ liệu khỏi AppDelegate. Về lý thuyết, tôi có thể sử dụng danh mục như một singleton, nhưng tôi chọn không như nó giới thiệu "độ cứng ứng dụng" như bạn đã nói. Ngoài ra, tôi sử dụng một số mã tùy chỉnh cho ngăn xếp Dữ liệu cốt lõi và điều này cho phép tôi thả mã này vào các dự án mới một cách dễ dàng. –

+1

Tôi đồng ý với bạn về việc sử dụng App Delegate để tạo ngăn xếp Dữ liệu cốt lõi. Tôi đang sử dụng một UITabBarController như điều khiển xem gốc của tôi, và tôi không chắc chắn làm thế nào để tuyên truyền bối cảnh cho đối tượng điều khiển đó, vì nó sống trong MainWindow.xib và tôi không chắc chắn làm thế nào để gán cho nó một con trỏ đến một ManagedObjectContext. Tôi nghĩ rằng tôi đang đăng một câu hỏi riêng cho việc này. – mvexel

+1

Tài liệu Apple đó nói, "Khi bạn tạo một bộ điều khiển xem, bạn vượt qua nó bối cảnh nó nên sử dụng." nhưng tôi không thấy CÁCH này được thực hiện. Bộ điều khiển chế độ xem chính được tạo thông qua bảng phân cảnh, nếu sử dụng bảng phân cảnh, phải không? Vì vậy, làm thế nào để vượt qua nó bối cảnh? –

28

Tôi có một lớp singleton mà tôi cho phép quản lý dữ liệu cốt lõi của mình và tôi không để nó trên ủy nhiệm ứng dụng. Tôi không thích lộn xộn lớp đại biểu ứng dụng với các phương pháp tôi có thể cần cho conviniece như lấy đối tượng nhất định vv

+1

Âm thanh thực tế với tôi. Tôi ngạc nhiên táo bao gồm nó các ứng cử viên đại biểu. –

+4

họ có thể làm điều đó bởi vì họ muốn thể hiện làm thế nào để làm điều đó và đó là nơi họ mặc dù nó sẽ là nơi thuận tiện để đưa nó từ các đại biểu ứng dụng là loại một singleton đã – Daniel

+3

có một đối tượng điều khiển dữ liệu lõi đơn làm cho hoàn toàn có ý nghĩa. chúng tôi có nó tóm tắt để nó có thể được tái sử dụng trong mọi dự án. +1 – stigi

11

tôi rời khỏi logic dữ liệu cốt lõi trong các đại biểu ứng dụng vì những lý do sau đây:

1) Tôi không thấy bất kỳ lợi thế thực sự nào trong việc di chuyển mã này trong các lớp khác: khái niệm về ủy nhiệm hoàn toàn được thực hiện bởi logic dữ liệu cốt lõi do ứng dụng ủy nhiệm xử lý vì mô hình dữ liệu cốt lõi thực sự là một phần cơ bản của ứng dụng của bạn;

2) Trong tất cả các mã mẫu tôi đã thấy, bao gồm các mẫu của Apple, dữ liệu cốt lõi được xử lý bởi ứng dụng ủy nhiệm;

3) Ngay cả trong sách Cốt lõi dữ liệu, thực tế phổ biến là yêu cầu ủy nhiệm ứng dụng xử lý mã liên quan đến dữ liệu cốt lõi;

4) Cá nhân tôi không nghĩ rằng khả năng đọc hay bất cứ điều gì khác thực sự được cải thiện bằng cách có lớp học đặc biệt cho dữ liệu cốt lõi, nhưng đây là vấn đề cá nhân và tôi sẽ không tranh luận ở đây phương pháp nào là tốt nhất. Đối với tôi, tính đơn giản trong khi giữ lại chức năng là quan trọng.

+0

Tôi thường thấy ngăn xếp Dữ liệu cốt lõi trong App Delegate. Tuy nhiên, mã tôi xem thường được tạo ra cho mục đích minh họa. Cách thực tế để thực hiện một cái gì đó đôi khi khác với ví dụ như vậy. Tôi không muốn theo dõi một cách mù quáng mã mẫu của Apple mà không có lý do chính đáng. Tôi có xu hướng nghĩ rằng bạn là chính xác trong giả định nó sẽ chỉ là một vấn đề của hương vị cá nhân với một vài lợi thế một trong hai cách. –

+3

Tôi cũng nghĩ rằng đối số 2 và 3, là vì trong hướng dẫn hoặc ví dụ bạn đang cố gắng giảm thiểu càng nhiều càng tốt bất kỳ mã nào không liên quan đến những gì bạn đang cố gắng trình bày - do đó việc thực hiện cơ chế của Singleton những gì được cho là một ví dụ đơn giản. Điều tôi không thích về việc giữ những thứ này trong App Delegate, là nó làm tăng số lượng thứ mà sau đó phải biết về App Delegate ... –

+0

"khái niệm về phái đoàn được hoàn thành một cách hoàn hảo bởi logic dữ liệu cốt lõi được xử lý bởi App delegate vì mô hình dữ liệu cốt lõi thực sự là một phần cơ bản của ứng dụng của bạn; " Không, UIApplication không ủy nhiệm bất kỳ trách nhiệm nào về chức năng Core Data cho đại biểu của nó. Bạn có thể quyết định rằng một cửa hàng liên tục là một mối quan tâm cấp ứng dụng, nhưng nó không phải là một phần của UIApplicationDelegate. – quellish

10

Câu hỏi tôi muốn tự hỏi, trong trường hợp của bạn, là "ai thực hiện ngăn xếp Dữ liệu cốt lõi" thuộc về "?" Các dữ liệu chính nó thực sự là tỉnh của ứng dụng, phải không? (Dữ liệu lõi CF trên máy Mac, nơi bạn có thể có một ứng dụng có khả năng làm việc với nhiều tài liệu cùng một lúc, do đó, ngăn xếp Dữ liệu cốt lõi thuộc về mỗi tài liệu.)

Trong mọi ứng dụng Cocoa/Cocoa Touch, App Delegate thường là phương tiện ưa thích của việc tùy chỉnh hành vi của ứng dụng, vì vậy đây là nơi tự nhiên cho ngăn xếp Dữ liệu cốt lõi.

Bây giờ, vấn đề tôi nghi ngờ bạn đang gặp phải là nó cảm thấy sai lầm khi liên tục viết những thứ như:

NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 

Những gì tôi thường làm trong những trường hợp này là viết chức năng (không phải phương pháp) như thế này:

NSManagedObjectContext *UIAppManagedObjectContext() { 
    return [*(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
} 

Tôi viết chức năng tương tự cho NSPersistentStoreCoordinatorNSManagedObjectModel. Tôi đặt tất cả các tệp này trong các tệp .h/.m của App Delegate, vì đây cũng là các đối tượng cấp ứng dụng.

+1

Thats vui nhộn. Đó chính xác là đoạn mã tôi không thích. Tôi không thích chạy đến App Delegate để biết thông tin lưu trữ tệp. Nó cảm thấy "sai". Điều đó khiến tôi đặt câu hỏi về cách các nhà phát triển khác xử lý tình huống này. –

+1

Lý do đoạn mã đầu tiên cảm thấy sai là do mã của nó có mùi. Gói trong một chức năng tiện dụng chỉ là chất khử mùi. Nó đơn giản hơn rất nhiều để chỉ đơn giản là vượt qua bối cảnh xung quanh để các đối tượng cần nó (sử dụng tiêm tài sản, chủ yếu). –

+2

Bạn nên * không * nhận bối cảnh từ ứng dụng đại biểu như thế này. Bạn nên chuyển ngữ cảnh từ một bộ điều khiển khung nhìn sang bộ điều khiển xem tiếp theo, như được trình bày trong tất cả các ví dụ của Apple. – mmalc

4

Tôi ủng hộ việc ủy ​​quyền ứng dụng biết nơi mô hình bắt đầu và có mô hình biết ngữ cảnh đối tượng được quản lý ở đâu. Dữ liệu cốt lõi - "ness" của mô hình có vẻ giống như một chi tiết thực hiện của mô hình với tôi, các lớp điều khiển (như ủy nhiệm ứng dụng) chỉ nên hỏi "cung cấp cho tôi thông tin này về mô hình" và mô hình nên biết cách trả lời câu hỏi đó. Vì vậy, có một đối tượng dữ liệu lõi có sẵn thông qua một đối tượng điều khiển có vẻ như một trừu tượng bị rò rỉ.

+0

Điều gì đó đã trở thành một vấn đề trong phát triển iPhone là sử dụng và cấu hình NSFetchedResultsControllers. Bạn cũng có thể có "Model" của bạn bây giờ làm thế nào để cấu hình và trả về NSFetcheResultsControllers, nhưng có vẻ như lớp mô hình sẽ có một chút cồng kềnh. Tôi cảm thấy như NSFetchedResultsControllers làm mờ dòng giữa bộ điều khiển và mã mô hình (không nhất thiết phải theo cách xấu). Gần đây tôi đã thực hiện điều này và một số ý tưởng khác vào cấu hình mới của tôi (thêm câu trả lời mới). –

+0

Tôi đồng ý với @Graham và đây là cách tôi làm điều đó. 'UIViewControllers' của bạn không cần phải gây rối với' NSManagedObjectContext', họ chỉ nên nói chuyện với mô hình và yêu cầu những gì họ cần. Cơ chế nhận thông tin đó không quan tâm đến bộ điều khiển xem của tôi. – kubi

6

Tôi sẽ chỉ liệt kê điều này trong câu trả lời mới.(Tôi đã loại bỏ lớp FJSCoreDataStack trước đó của tôi để ủng hộ điều này)

Cách xử lý mới của tôi là sử dụng một danh mục trên NSManagedObjectContext. Ive đã thêm các phương thức lớp sau:

+ (NSManagedObjectContext *)defaultManagedObjectContext; 
+ (NSManagedObjectContext *)scratchpadManagedObjectContext; 
+ (NSManagedObjectModel *)managedObjectModel; 
+ (NSPersistentStoreCoordinator *)persistentStoreCoordinator; 
+ (NSString *)applicationDocumentsDirectory; 

Điều này giúp mọi thứ không được ủy quyền ứng dụng và cho phép truy cập đơn nên tôi chọn sử dụng. Tuy nhiên, tôi vẫn sử dụng tiêm phụ thuộc từ App Delegate (như mmalc đã nói, nó giới thiệu tính không linh hoạt vào mã của tôi). Tôi chỉ đơn giản là di chuyển tất cả các "Core Data Stack" mã vào NSManagedObjectCOntext Category.

Tôi thích chuyển tham chiếu xung quanh, đặc biệt là vì tôi có phương pháp "ngữ cảnh bàn phím" đẹp. Điều này giữ cho bộ điều khiển View của tôi linh hoạt vì tôi chưa cam kết chúng với "defaultManagedObjectContext".

Cũng liên quan đến cuộc trò chuyện trong thế giới iPhone (và có thể có một ảnh hưởng trên kiến ​​trúc của bạn): NSFetchedResultsController and constructing NSFetchRequests

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