тип получателя ***, например, сообщение - это предварительное объявление


199

В моем приложении iOS5 у меня есть NSObject Statesкласс, и я пытаюсь его инициировать:

states = [states init];

вот initметод в States:

- (id) init
{
    if ((self = [super init]))
    {
        pickedGlasses = 0;
    }

    return self;
}

Но есть ошибка в строке states = [states init];

Приемник типа "Состояния", например, сообщение является предварительной декларацией

Что это означает? Что я делаю не так?


Я пытался найти тот же вопрос, но в каждом из них есть свое решение. Я немного
запутался

3
Очень короткий ответ: вы либо пропускаете #import (возможно, в файле префикса), либо пропускаете "@class Abc;" строка (то есть в файле .h чуть выше строки
@interface

Ответы:


440

Это в основном означает, что вам нужно импортировать файл .h, содержащий декларацию состояний.

Однако в вашем коде много других проблем.

  • Вы вводите объект без +allocнего. Это не сработает
  • Вы объявляете объект как тип без указателя, который также не будет работать
  • Вы не вызывая [super init]в -init.
  • Вы объявили класс, используя @classв заголовке, но никогда не импортировали класс.

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

Что за нелепая формулировка. Но да, это исправило это.
TimJowers2

Если вы пытаетесь использовать объекты Swift в Objective-C, не забывайте, что они должны наследоваться от NSObject.
Михал Шрůтек

27

FWIW, я получил эту ошибку, когда я внедрил основные данные в существующий проект. Оказалось, я забыл связать CoreData.h с моим проектом. Я уже добавил инфраструктуру CoreData в свой проект, но решил проблему, связавшись с инфраструктурой в моем предварительно скомпилированном заголовке, как это делают шаблоны Apple:

#import <Availability.h>

#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import <CoreData/CoreData.h>
#endif

2
Как жаль, что почти все учебные пособия по CoreData начинаются с использования шаблона, но не с существующим проектом. Здесь довольно легко ошибиться.
Yeung

24

Я получил такое сообщение, когда у меня было два файла, которые зависели друг от друга. Сложность в том, что вы получите циклическую ссылку, если просто попытаетесь импортировать друг друга (класс A импортирует класс B, класс B импортирует класс A) из их заголовочных файлов. Поэтому вместо этого поместите объявление forward ( @class A) в заголовочный файл одного из классов (класса B). Тем не менее, при попытке использовать ивар класса A в реализации класса B возникает эта ошибка, просто добавление #import "A.h"в файл .m класса B решило проблему для меня.


16

Я пытался использовать @class "Myclass.h".

Когда я изменил его #import "Myclass.h", он работал нормально.


Просто примечание: @class "Myclass.h"совершенно неверно. @class Myclassдолжен использоваться в заголовочном файле, где класс не может быть импортирован (из-за циклических ссылок, как, например, в случае с классом, определенным Swift в Objective-C), но #import "Myclass.h"должен использоваться, если он может быть импортирован.
Пользователь, который не является пользователем

6

Ты используешь

States states;

где, как вы должны использовать

States *states;

Ваш метод инициализации должен быть таким

-(id)init {
  if( (self = [super init]) ) {
      pickedGlasses = 0;
  }
  return self;
}

Теперь, наконец, когда вы собираетесь создать объект для класса States, вы должны сделать это следующим образом.

State *states = [[States alloc] init];

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


5

Если вы получаете эту ошибку при попытке использовать класс или метод Swift в Objective C : вы забыли один из двух шагов, определенных Apple на этой диаграмме:

введите описание изображения здесь

Пример:

Ошибка отображается в вашем Test.mфайле:

Получатель MyClass для сообщения класса является предварительным объявлением

Шаг 1: проверьте, что Test.hесть

@class MyClass;

Шаг 2: найдите *-Swift.hимя файла в настройках сборки (ищите Имя заголовка сгенерированного интерфейса Objective-C ). Имя будет что-то вродеMyModule-Swift.h

Шаг 3: проверьте, что Test.mимпортирует вышеуказанный заголовок

#import "MyModule-Swift.h"

3

Проверьте, импортировали ли вы заголовочные файлы классов, которые выдают эту ошибку.


1

Убедитесь, что прототип для вашего метода модуля находится в файле .h.

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


0

Есть два связанных сообщения об ошибках, которые могут сказать вам, что что-то не так с объявлениями и / или импортом.

Первый - это тот, на который вы ссылаетесь, который может быть сгенерирован, НЕ помещая #import в ваш .m (или .pch файл) при объявлении @class в вашем .h.

Второе, что вы можете увидеть, если у вас есть метод в вашем классе States, например:

- (void)logout:(NSTimer *)timer

после добавления #import это:

Нет видимого @interface для "States" объявляет селектор 'logout:'

Если вы видите это, вам нужно проверить и объявить, объявили ли вы свой метод выхода из системы (в данном случае) в файле .h класса, который вы импортируете или пересылаете.

Так что в вашем случае вам понадобится:

- (void)logout:(NSTimer *)timer;

в классе вашего штата .h, чтобы одна или обе из этих связанных ошибок исчезли.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.