it-swarm.com.ru

Ошибка "Ожидаемый тип", указывающая на тип возвращаемого значения метода

Я пытался скомпилировать, но каждый раз, когда я это делаю, один метод выдает странную ошибку «ожидаемый тип». У меня есть метод в шапке:

-(ANObject *)generateSomethingForSomethingElse:(NSString *)somethingElse;

Ошибка указывает на тип возвращаемого значения для этого метода. Я импортировал ANObject в заголовок, используя #import "ANObject.h", и ANObject нормально компилируется ..

Почему это происходит?

41
Ollie Hirst

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

var value = someMethod();

function someMethod()
{
    ...
}

Это может вызвать ошибку во время компиляции, потому что someMethod () еще не определен. То же самое относится и к классам. Классы компилируются один за другим компилятором.

Итак, если вы представляете, что все классы помещаются в гигантский файл перед компиляцией, вы, возможно, уже сможете увидеть проблему. Давайте посмотрим на классы Ship и BoatYard:

@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end

@interface Ship : NSObject
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end

Еще раз, поскольку класс Ship еще не определен, мы пока не можем ссылаться на него. Решение этой конкретной проблемы довольно просто; изменить порядок компиляции и скомпилировать. Я уверен, что вы знакомы с этим экраном в XCode:

 

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

Но что, если вы не хотите этого делать, или, что более важно, что, если между двумя объектами существует круговая связь? Давайте увеличим сложность этой диаграммы объекта, добавив ссылку на текущий BoatYard, в котором находится Ship:

@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end

@interface Ship : NSObject
@property (nonatomic, retain) BoatYard* currentBoatYard;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end

О, дорогой, теперь у нас есть проблема. Эти два не могут быть скомпилированы бок о бок. Нам нужен способ сообщить компилятору, что класс Ship * действительно существует. И именно поэтому ключевое слово @class так удобно. 

Чтобы выразить это с точки зрения непрофессионала, вы говорите: «Поверь мне, чувак, Ship действительно существует, и ты это скоро увидишь». Чтобы сложить все вместе:

@class Ship;

@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end

@interface Ship : NSObject
@property (nonatomic, retain) BoatYard* currentBoatYard;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end

Теперь компилятор знает, как он компилирует BoatYard, что вскоре появится определение класса Ship. Конечно, если это не так, компиляция все равно будет успешной.

Однако все ключевое слово @class сообщает компилятору, что класс скоро появится. Это not замена #import. Вы все равно должны импортировать файл заголовка, иначе у вас не будет доступа ни к одному из внутренних компонентов класса:

@class Ship

-(void) example
{
    Ship* newShip = [[Ship alloc] init];
}

Это не может работать и завершится ошибкой с сообщением об ошибке, в котором говорится, что Корабль является предварительным объявлением. После того как вы #import "Ship.h", вы сможете создать экземпляр объекта.

92
Steve Rukuts

Я обнаружил, что эта ошибка возникает, когда существует круговая зависимость от заголовков. Проверьте, импортируется ли файл .h, где вы объявляете этот метод, в ANObject.h

53
RENA

Вы в основном добавляете

@class ANObject;

до @интерфейс!

25
JomanJi

Итак, по какой-то причине я получаю эту ошибку при попытке установить метод с типом enum в параметрах. Вот так:

- (void)foo:(MyEnumVariable)enumVariable;

Раньше я использовал это, как это, и никогда не было проблемы, но теперь я сделал. Я проверил круговую зависимость и не смог найти ни одной. Я также проверил на наличие опечаток несколько раз и никаких кубиков. В итоге моя проблема была решена добавлением enum до того, как я захотел получить доступ к переменной. Вот так:

- (void)foo:(enum MyEnumVariable)enumVariable;
{
     enum MyEnumVariable anotherEnumVariable;
}
4
OlivaresF

Я получил это сообщение, когда тип переменной был написан с ошибкой. Смотри ниже это ниже

например.

-(void)takeSimulatorSafePhotoWithPopoverFrame:(GCRect)popoverFrame {

вместо.....

-(void)takeSimulatorSafePhotoWithPopoverFrame:(CGRect)popoverFrame {
1
sean808080

Обычно, когда я вижу такую ​​ошибку, это потому, что у меня есть опечатка в предыдущей строке, такая как лишние или отсутствующие скобки или что-то еще.

1
Dave DeLong

Это может звучать глупо, но неправильный обстрел или неправильное использование прописных/строчных букв неверно.

1
Yeung

Как ни странно, изменение порядка моего импорта исправило это в прошлом ... Попробуйте переместить импорт в конец после всех других ваших импортов.

0
DranoMax