2011-12-28 2 views
6

Я работал над проектом Xcode, и все было замечательно, пока два моих класса не перестали признавать друг друга. Вот отрывок:Классы Xcode не могут «видеть» друг друга

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

По какой-то причине я получаю ошибку «Неизвестное имя типа„JBXViewController“, вы имели в виду„UIViewController“?» Я не понимаю, как это возможно, так как я импортирую другой класс всего на несколько строк выше. Любые идеи были бы очень оценены!

+0

Вы также импортируете ViewController2.h в JBXViewController.h? –

+0

должна быть проблема с «JBXViewController.h». можете ли вы опубликовать некоторый исходный код из класса JBXViewController? – samfisher

+0

@FirozeLafeer: Я ввожу ViewController2.h в JBXViewController.h – Rob

ответ

11

Когда вы говорите, что они «не могут видеть друг друга», я предполагаю, что вы имеете в виду, что вы также импортируете ViewController2.h в свой JBXViewController.h. Таким образом, вы один заголовок импорта другой заголовок, который импортирует первый заголовок, который импортирует второй, который импортирует первый раз ...

Вместо этого используйте косую ссылку на JBXViewController:

@class JBXViewController; 

@interface ViewController2 : UIViewController { 
    JBXViewController *jbx; 
} 

А потом #import "JBXViewController.h" в вашей реализации вместо этого (в вашем ViewController2.m)

5

Ответ Фироза Лафера верен, но эта проблема, вероятно, является симптомом плохого дизайна вашего кода.

Я предполагаю, что в вашем приложении JBXViewController является родительским контроллером представления, и он иногда показывает ViewController2 для определенной функции. (Например, JBXViewController показывает список записей, а ViewController2 редактирует одну из записей.) В такой ситуации ViewController2 не должен знать детали JBXViewController. Вместо этого JBXViewController должен предоставить ViewController2 необходимые ему данные с помощью свойств ViewController2, и если ViewController2 должен вызывать методы в JBXViewController, они должны быть частью протокола делегата.

Например, предположим, что JBXViewController в настоящее время имеет следующее свойство, и ViewController2 обращается к нему:

@property (strong) JBXObject * currentObject; 

Вы должны вместо этого иметь currentObject собственности на ViewController2 и JBXViewController должны установить его, прежде чем показывать контроллер представления:

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

Это работает для односторонней связи. JBXViewController может предоставить данные ViewController2. Если данные должны возвращаться к JBXViewController (кроме изменения параметров currentObject), вы должны настроить делегат для ViewController2. Например:

@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 

Тогда же JBXViewController соответствовать протоколу:

@interface JBXViewController : UIViewController <ViewController2Delegate> 

Установите делегат, либо в Interface Builder или в коде следующим образом:

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

И реализовать все методы, перечисленные в ViewController2Delegate.

Вместе эти изменения означают три вещи:

  1. ViewController2 не нужны специальные знания о том, как работает JBXViewController. Это означает, что вам больше не нужно импортировать JBXViewController.h в ViewController2.ч, что решает вашу непосредственную проблему.

  2. JBXViewController теперь более гибкий. Пока он устанавливает соответствующие свойства в ViewController2 и реализует любые необходимые методы делегирования, вы можете изменить все, что захотите, в JBXViewController, а ViewController2 никогда не узнает и не позаботится об этом.

  3. ViewController2 теперь более гибкий. Вы можете использовать его из других частей приложения или перенести в другое приложение. Вы можете вставить экран между JBXViewController и ViewController2.

Эти изменения не нужны, чтобы приложение работало на вашем устройстве и функционировало так, как вы планируете. Но у вас будет более легкое время в пути, если вы начнете использовать такие проекты.

+0

Брент, я подозреваю, что ты прав. Благодарим вас за подробный ответ, и я обязательно переосмыслию способ структурирования кода. – Rob

Смежные вопросы