2012-01-18 33 views
9

Tôi đang làm việc trên ứng dụng dựa trên tài liệu Mac đầu tiên của mình.NSDocumentController currentDocument return nil

Tôi đã subclassed NSDocument, reimplementing các phương pháp như

- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError; 
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError; 
- (void)makeWindowControllers; 

Bộ điều khiển cửa sổ chính là một lớp con của NSWindowsController, có chứa hai NSViewController lớp con.

Sự cố tôi đang gặp phải là tôi cần có quyền truy cập vào tài liệu hiện tại từ các trình điều khiển chế độ xem này. Những gì tôi làm là gọi

MyDocument *myDocument = [[NSDocumentController sharedController] currentDocument]; 

Lúc đầu, ngay sau khi bắt đầu ứng dụng, một tài liệu mới được tạo. Sau đó, cửa sổ chính và bộ điều khiển chế độ xem của nó được tạo, nhưng phương thức trên trả về nil. Dưới đây là các bản ghi (sử dụng NSLog) tôi nhận được:

Just created this new document: <MyDocument: 0x10040ff10> 
I'm in a view controller and current document is (null) 

Sau đó, tạo ra một tài liệu mới và gọi phương pháp này kết quả trong một con trỏ không bằng không, nhưng nó không trỏ vào tài liệu đúng, nhưng cho người đầu tiên:

Just created this new document: <MyDocument: 0x100437e10> 
I'm in a view controller and current document is <MyDocument: 0x10040ff10> 

Lưu ý rằng sau khi tạo tài liệu thứ hai, currentDocument trỏ đến tài liệu đầu tiên và không chuyển sang tài liệu thứ hai.

Bất kỳ ý tưởng nào về những gì tôi thiếu hoặc làm sai ở đây? Khi nào là currentDocument được đặt cho NSDocumentController?

Trả lời

2

Từ các tài liệu của Apple trên NSDocumentControllercurrentDocument nó nói:

Phương pháp này lợi nhuận Nil nếu nó được gọi khi ứng dụng của nó không phải là hoạt động. Điều này có thể xảy ra trong quá trình xử lý thao tác kéo và thả, ví dụ: , trong khi triển khai readSelectionFromPasteboard :. Trong một trường hợp như vậy, gửi thông báo sau thay vì từ một NSView lớp con gắn liền với tài liệu:

[[[self window] windowController] document];

Đây là một chút mơ hồ như nó không thực sự đủ điều kiện gì "không hoạt động" nghĩa là gì. Có thể là thao tác kéo thả n 'là trình kích hoạt duy nhất nhưng nó không cho biết đó có phải là trình kích hoạt duy nhất cho ứng dụng không hoạt động hay không.

Có thể phương án thay thế được đề xuất bởi Apple sẽ được sử dụng cho bạn.

+0

Cảm ơn, nhưng tôi đã thử điều đó và tôi vẫn nhận được kết quả là không. Tôi cũng không chắc chắn về những gì "không hoạt động" có nghĩa là cho Apple, nhưng trong trường hợp của tôi nó xảy ra ngay sau khi bắt đầu ứng dụng. Không kéo và thả, không có gì đặc biệt. – msoler

0

Bất kỳ lý do bạn không thể gọi -[self document] từ NSWindowController lớp con của bạn (hoặc -[[self window] document] trong NSViewController lớp con của bạn? Đó là bình thường thế nào điều này được thực hiện trong một ứng dụng tài liệu-có trụ sở tại Cocoa.

Về cơ bản khi NSDocument (phân lớp) được tạo ra, sau đó tạo tất cả các NSWindowControllers và đính kèm chúng vào tài liệu.

Quan trọng hơn, [[NSDocumentController sharedController] currentDocument] sẽ không trả lại thông tin phù hợp nếu bạn có 2 tài liệu mở và đột nhiên cần phải vẽ nội dung của cả hai. Thay vào đó, NSWindowController có nghĩa vụ kiểm soát luồng thông tin cho các chế độ xem trong cửa sổ để bạn có thể quản lý thay đổi nền trước và nền cùng một lúc (chẳng hạn như có thể xảy ra nếu cửa hàng sao lưu cho tất cả các cửa sổ trong ứng dụng của bạn cần làm mới cùng một lúc).

+0

Cảm ơn. Từ lớp con NSViewController nó không thể truy cập vào tài liệu bằng cách gọi '[[cửa sổ tự] tài liệu]' như NSViewController có thuộc tính _view_ nhưng không phải là thuộc tính _window_. Sử dụng tài liệu '[[cửa sổ tự] windowController]]' từ một tài liệu NSView và '[[[cửa sổ tự xem] windowController]' (như được chỉ bởi @roger) từ một NSViewController làm việc và trả về đúng tài liệu. Điều quan trọng cần đề cập đến là họ làm việc một khi các cửa sổ/khung nhìn đã được khởi tạo, điều đó là tốt và dễ hiểu đối với tôi. – msoler

+0

Xin lỗi, tôi đã bỏ lỡ thực tế bạn đang sử dụng NSViewControllers. Tôi đã thêm một câu trả lời mà đi nhiều hơn với mô hình MVC khi sử dụng NSViewControllers. Hy vọng cái này hữu ích hơn. – gaige

6

(Tôi để lại câu trả lời trước đó vì nó trả lời câu hỏi khi được yêu cầu cho một lớp con của NSView, nhưng bây giờ áp phích ban đầu đã tuyên bố rằng anh ta đang sử dụng NSViewController, có những cân nhắc khác nhau).

Trong trường hợp của NSViewController chế độ xem được kiểm soát, NSViewController được thiết kế để gắn liền với dữ liệu của nó bằng cách sử dụng thuộc tính representedObject. Sự trừu tượng này được dự định sẽ được quản lý bởi bộ điều khiển chứa của NSViewController, có vẻ như là NSWindowController của bạn.

Tùy thuộc vào số lượng đóng gói bạn muốn/cần cung cấp, bạn có thể đẩy tài liệu vào NSViewControllers (nếu chúng hoạt động trên toàn bộ tài liệu) hoặc chỉ đẩy thông tin từ tài liệu đó là germane đến NSViewController cụ thể .

Ví dụ: tôi sẽ giả sử một phần mềm chỉnh sửa thông tin thiết kế về một chuyến tàu: động cơ, ô tô và caboose. Lớp con NSDocument chứa một đối tượng động cơ duy nhất, một đối tượng caboose duy nhất và 0 hoặc nhiều đối tượng ô tô hơn. Trong trường hợp này, bạn có thể có 3 NSView s, mỗi số có NSViewController riêng để xử lý di chuyển dữ liệu vào và ra khỏi chế độ xem từ đối tượng của chúng.

Bộ điều khiển NSWindowController xử lý từng thiết lập của từng đối tượng mà nó hiểu được. Ví dụ, khi các quan điểm hoàn thành tải, bộ điều khiển cửa sổ sẽ sau đó:

[engineViewController setRepresentedObject: engine]; 
    [cabooseViewController setRepresentedObject: caboose]; 

Sau đó, bạn có thể sử dụng một NSTableView để hiển thị danh sách các xe hơi, và (khi một chiếc xe đang được xem), bộ điều khiển cửa sổ có thể sau đó sử dụng [carViewController setRepresentedObject: car]; khi lựa chọn được thay đổi (hoặc bạn có thể sử dụng các ràng buộc, tùy thuộc vào cách mã của bạn được cấu trúc). Bằng cách này, bạn tận dụng lợi thế tốt nhất của mô hình MVC, vì các bộ điều khiển liên kết các khung nhìn với các mô hình khi cần thiết, nhưng cấu trúc tài liệu chỉ thực sự được hiểu bởi cấp cao nhất NSWindowController.