接收器类型***用于实例消息是一个前向声明。

217

在我的iOS5应用中,我有一个NSObjectStates类,并尝试进行初始化:

states = [states init];

这里有一个在States中的init方法:

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

    return self;
}

但是在states = [states init];这一行中出现了错误。

实例消息的接收器类型“States”是前向声明。

这是什么意思?我做错了什么?


我尝试寻找相同的问题,但每个答案都不同。我有点困惑。 - SentineL
4
简短回答是你可能缺少了一个 #import(也许在你的 Prefix 文件中)或者缺少了一个 "@class Abc;" 行(即在 .h 文件中,在 @interface 行上方)。 - Fattie
还要确保如果这是一个Swift类,并且您正在使用“@objc(ClassName)”,则此名称与您的类名定义匹配。大小写敏感。 - danroose
9个回答

463

这基本意味着你需要导入包含状态声明的.h文件。

然而,你的代码还有很多其他问题。

  • 你正在初始化一个对象,但未使用+alloc来分配内存。这样是行不通的。
  • 你将一个对象声明为非指针类型,这也不起作用。
  • 你在-init中没有调用[super init]
  • 你在头文件中使用@class声明该类,但没有导入该类。

这有点奇怪,因为在我的情况下,我只是因为循环引用问题而删除了.h文件。 - Alper
多么荒谬的措辞。但是没错,那解决了问题。 - TimJowers2
3
如果您想在Objective-C中使用Swift对象,请不要忘记它们必须从NSObject继承。 - Michal Šrůtek
当将'MyProject-Swift.h'置于#ifdef FB_SONARKIT_ENABLED或#if DEBUG时,您也可能在模拟器中工作但构建发布版本时出现此错误。 - scbojer

28

顺便提一下,当我将核心数据导入到现有项目中时,出现了这个错误。结果发现我忘记将CoreData.h链接到我的项目中。虽然我已经将CoreData框架添加到项目中,但通过像苹果的模板一样在预编译头文件中链接到该框架来解决问题。

#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

26

当我有两个相互依赖的文件时,我遇到了这种消息。这里的棘手问题是,如果你只是尝试从它们的头文件中互相导入(类A导入类B,类B导入类A),那么你会得到一个循环引用。因此,你需要在一个类(类B)的头文件中使用前向声明(@class A)代替。然而,在类B的实现中试图使用类A的ivar时,就会出现这个错误,只需在类B的.m文件中添加#import "A.h"即可解决问题。


18

我曾试图使用 @class "Myclass.h"

当我改为#import "Myclass.h"时,它很好地工作了。


1
这里只是一个小提示:@class "Myclass.h" 是完全不正确的。在头文件中应该使用 @class Myclass,当类无法导入时(由于循环引用,例如在 Objective-C 中定义 Swift 类时会发生这种情况),但如果可以导入,则应该使用 #import "Myclass.h" - ReinstateMonica3167040

14

如果您在尝试在Objective-C中使用Swift类或方法时遇到此错误:您忘记了苹果在此图表上定义的两个步骤之一:

enter image description here

示例:

您的Test.m文件中出现错误:

类消息的接收器'MyClass'是一个前向声明

在Obj-C文件中:

步骤1:检查Test.h是否有

@class MyClass;

步骤2:在“构建设置”中查找Objective-C Generated Interface Header Name(查找*-Swift.h文件名)。名称将类似于MyModule-Swift.h
步骤3:检查Test.m是否导入上述头文件。
#import <MyModule/MyModule-Swift.h>

在Swift文件中:

  • 确保MyClass(或其基类)继承NSObject类。
  • 确保每个你想从Obj-C调用的方法前面有@objc
  • 还要检查目标成员资格部分(在文件检查器中)。

6

您正在使用

States states;

你应该使用

States *states;

你的初始化方法应该像这样:
-(id)init {
  if( (self = [super init]) ) {
      pickedGlasses = 0;
  }
  return self;
}

现在,当您要为States类创建对象时,应该像这样进行操作。
State *states = [[States alloc] init];

我并不是说这是最好的方法。但它可能会帮助您理解初始化对象的基本用法。


4

请检查是否导入了抛出此错误的类的头文件。


那很容易。 - outrowender

1

请确保您的单元方法原型在.h文件中。

因为您在文件中调用方法的位置高于定义它的位置,所以会出现此消息。或者,您可以重新排列方法,使调用者在文件中的位置低于它们调用的方法。


0

有两个相关的错误消息可能会告诉您声明和/或导入存在问题。

第一个是您所指的,如果在.h中声明@class而在.m(或.pch文件)中没有放置#import,则会生成该消息。

第二个错误消息可能会出现在您的States类中有一个方法,例如:

- (void)logout:(NSTimer *)timer

添加 #import 后是这样的:

“States”没有声明名为“logout:”的选择器

如果您看到这个错误,需要检查并确认您是否在导入或转发的类的 .h 文件中声明了“logout”方法(在此示例中)。

因此,在您的情况下,您需要:

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

在您的States类的.h文件中,可以使其中一个或者两个相关错误消失。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接