2011-12-28 32 views
6

Tôi đang làm việc trên một dự án Xcode và mọi thứ đều tuyệt vời, cho đến khi hai lớp của tôi ngừng nhận ra nhau. Dưới đây là một đoạn trích:Các lớp Xcode không thể "nhìn thấy" nhau

#import "JBXViewController.h" 
@interface ViewController2 : UIViewController { 
    JBXViewController *jbx; 
} 

Đối với một số lý do tôi nhận được lỗi "Tên Loại không xác định 'JBXViewController', bạn đã có nghĩa là 'UIViewController'?" Tôi không hiểu làm thế nào điều này là có thể, vì tôi đang nhập khẩu các lớp khác chỉ là một vài dòng ở trên. Bất kỳ thông tin chi tiết nào cũng sẽ được đánh giá cao!

+0

Bạn cũng đang nhập ViewController2.h trong JBXViewController.h? –

+0

phải có vấn đề với "JBXViewController.h". u có thể đăng một số mã ban đầu từ lớp JBXViewController? – samfisher

+0

@ FirozeLafeer: Tôi đang nhập ViewController2.h vào JBXViewController.h – Rob

Trả lời

11

Khi bạn nói rằng họ "không thể nhìn thấy nhau", tôi giả sử bạn có nghĩa là bạn cũng đang nhập ViewController2.h trong JBXViewController.h của bạn. Vì vậy, bạn đã một tiêu đề nhập khẩu khác tiêu đề, trong đó nhập khẩu tiêu đề đầu tiên, trong đó nhập khẩu thứ hai, trong đó nhập khẩu là người đầu tiên một lần nữa ...

Thay vào đó, sử dụng một tài liệu tham khảo về phía trước để JBXViewController:

@class JBXViewController; 

@interface ViewController2 : UIViewController { 
    JBXViewController *jbx; 
} 

Và sau đó Thay vào đó, hãy thực hiện #import "JBXViewController.h" trong triển khai của bạn (trong ViewController2.m)

5

Câu trả lời của Firoze Lafeer là chính xác, nhưng vấn đề này có thể là một triệu chứng của thiết kế kém trong mã của bạn.

Tôi giả định rằng, trong ứng dụng của bạn, JBXViewController là bộ điều khiển chế độ xem gốc và đôi khi hiển thị một ViewController2 cho một số chức năng cụ thể. (Ví dụ, JBXViewController hiển thị một danh sách các bản ghi, trong khi ViewController2 chỉnh sửa một trong các bản ghi.) Trong một tình huống như thế này, ViewController2 không nên biết chi tiết của JBXViewController. Thay vào đó JBXViewController sẽ cung cấp cho ViewController2 dữ liệu cần thiết thông qua các thuộc tính của ViewController2 và nếu ViewController2 phải gọi các phương thức trên JBXViewController, chúng phải là một phần của giao thức đại biểu.

Ví dụ, giả JBXViewController hiện có tính chất sau đây, và ViewController2 truy cập nó:

@property (strong) JBXObject * currentObject; 

Bạn thay vào đó nên có một tài sản currentObject trên ViewController2, và JBXViewController nên đặt nó trước khi hiển thị các điều khiển xem:

self.myViewController2.currentObject = self.currentObject; 
[self.navigationController pushViewController:self.myViewController2 animated:YES]; 

Điều này phù hợp với giao tiếp một chiều — JBXViewController có thể cung cấp dữ liệu ViewController2. Nếu dữ liệu cần dòng chảy trở lại lên JBXViewController (không phải bằng cách thay đổi thuộc tính currentObject), bạn nên thiết lập một đại biểu cho ViewController2. Ví dụ:

@protocol ViewController2Delegate; // forward declaration 
@interface ViewController2 : UIViewController 
@property (weak) id <ViewController2Delegate> delegate; 
... 
@end 

@protocol ViewController2Delegate <NSObject> 
- (void)viewController2ShouldSave:(ViewController2*)viewController2; 
- (BOOL)viewController2:(ViewController2*)viewController2 shouldAddSomoflange:(JBXSomoflange*)aSomoflange; 
@end 

Sau đó đã JBXViewController phù hợp với các giao thức:

@interface JBXViewController : UIViewController <ViewController2Delegate> 

Đặt các đại biểu, hoặc trong Interface Builder hoặc trong mã như vậy:

self.myViewController2.delegate = self; 
self.myViewController2.currentObject = self.currentObject; 
[self.navigationController pushViewController:self.myViewController2 animated:YES]; 

Và thực hiện tất cả các các phương thức được liệt kê trong ViewController2Delegate.

Cùng nhau, những thay đổi này có nghĩa là ba điều:

  1. ViewController2 không cần kiến ​​thức cụ thể về cách JBXViewController hoạt động. Điều này có nghĩa là bạn không còn phải nhập JBXViewController.h trong ViewController2 nữa.h, giải quyết vấn đề trước mắt của bạn.

  2. JBXViewController hiện linh hoạt hơn. Miễn là nó đặt các thuộc tính thích hợp trong ViewController2 và thực hiện bất kỳ phương thức đại biểu cần thiết nào, bạn có thể thay đổi bất cứ thứ gì bạn muốn trong JBXViewController và ViewController2 sẽ không bao giờ biết hoặc quan tâm đến nó.

  3. ViewController2 giờ đây cũng linh hoạt hơn. Bạn có thể sử dụng nó từ các phần khác của ứng dụng hoặc di chuyển nó sang ứng dụng khác. Bạn có thể chèn một màn hình giữa JBXViewController và ViewController2.

Những thay đổi này không cần thiết để ứng dụng chạy trên thiết bị của bạn và hoạt động theo cách bạn dự định. Nhưng bạn sẽ có một thời gian dễ dàng hơn xuống đường nếu bạn bắt đầu áp dụng các loại thiết kế.

+0

Brent, tôi nghi ngờ bạn là đúng. Cảm ơn bạn đã trả lời chi tiết và tôi chắc chắn sẽ suy nghĩ lại cách mã được cấu trúc. – Rob

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