运行时出现“ Interface Builder文件中的未知类<MyClass>”错误


260

即使Interface Builder知道了MyClass,我在启动应用程序时也会收到错误消息。

当它MyClass是库的一部分时,会发生这种情况,如果直接在应用程序目标中编译该类,则不会发生这种情况。


您如何链接到图书馆?
Elise van Looij,2009年

我使用一个从属子项目,并将Xcode子项目的产品拖放到当前目标的“使用库链接二进制文件”构建阶段。
jhoule

如果该类来自CocoaPods,则可能对github.com/CocoaPods/CocoaPods/issues/491有所帮助。
协议

Answers:


222

尽管在运行时显示了“ Interface Builder文件中的Unclass类MyClass。 ”错误,但此问题与Interface Builder无关,而与链接器无关,后者不链接类,因为没有代码直接使用它。

当在运行时加载.nib数据(从.xib编译)时,MyClass使用字符串进行引用,但是链接器不会分析代码功能,而只是分析代码是否存在,因此它不知道。由于没有其他源文件引用该类,因此链接程序在创建可执行文件时会对其进行优化,使其不存在。因此,当Apple的代码尝试加载此类时,它找不到与之关联的代码,并打印警告。

默认情况下,Objective-C目标将-all_load -ObjC默认设置标志,该标志将保留所有符号。但是我从C ++目标开始,却没有。但是,我找到了解决该问题的方法,该方法使链接程序具有攻击性。

我最初使用的技巧是添加一个空的静态例程,例如:

+(void)_keepAtLinkTime;

它什么也没做,但是我会打一次,例如:

int main( int argc, char** argv )
{
   [MyClass _keepAtLinkTime];
   // Your code.
}

这将迫使链接器保留整个类,并且错误消失。

正如jlstrecker在评论中指出的那样,我们实际上并不需要添加_keepAtLinkTime方法。只需调用一个现有的,例如:

   [MyClass class];

(只要您从派生NSObject)就可以了。

当然,您可以在代码的任何位置调用它。我想它甚至可能是无法访问的代码。这样做的目的是欺骗链接器以使其MyClass在某个地方使用过,以至于它在优化它时并不那么积极。

Xcode 6.3.2和Swift 1.2

Swift的视图定义。确保覆盖init(coder aDecoder: NSCoder)。视图控制器的Objective-C定义。并且,在一棵洋梨树的鸟嘴。

将模块名称添加到Nib详细信息检查器中,在此处选择您的课程。


2
.xib数据不会在运行时加载。IB编译器将xib编译为笔尖;笔尖是在运行时加载的内容。
Peter Hosey,

19
您不必修改MyClass。只需调用它继承的方法即可NSObject,例如+class
jlstrecker 2011年

10
发布原始问题时,虽然它不是Xcode 4,但似乎仍然合适。在Xcode 4中,您可以MyClass.m在File Inspector的Target Membership部分中检查所有所需的目标,而不是添加一些虚拟方法来消除错误。
2011年

51
现在,另一种可能性是MyClass.m可能不在您的“编译源”构建阶段。如果将MyClass.h / m拖到项目中,而不是使用“新建文件”创建它们,则会发生这种情况。
史蒂芬·费舍尔

6
@JoshBruce您能解释一下Swift解决方案吗?我不太了解
Ryan Bobrowski

183

我按照劳拉的建议修复了此问题,但不需要重新创建文件。

  • 使用XCode 4,在Project Navigator中,选择包含其抱怨的类的.m文件。

  • 转到查看->实用工具->显示文件检查器
    (这将在右侧显示文件检查器,并带有.m文件信息)

  • 打开“ 目标成员身份”部分,并确保为此.m文件选择了目标

当我将.m文件添加到项目中时,由于某种原因它没有将其添加到默认目标中,这导致我得到您提到的错误。


的确,有时链接器错误是由于首先没有直接在目标中编译文件而导致的。您所描述的是控制与文件关联的目标的方法。不幸的是,我的文件已经是我目标的一部分,但仍然存在链接问题。这可能是由于我的库是C ++(而不是Objective-C),它具有不同的默认链接器标志(请参见上述Alasdair Allan和Sijo的文章)。
jhoule 2011年

5
该建议对我有用,尽管有所不同,因为我的“目标成员身份”复选框已选中。我取消选中它并重新构建,但是错误消息更改为指示我的新类名。再次选中该框并再次构建,一切正常。比删除缓存文件容易得多!
Electromaggot

通过Xcode UI的出色解决方案。@electromaggot,当您手动添加类时,Xcode可能会感到困惑,因此您可能需要添加多个文件。
戈嫩2012年

这也是我的解决方案。我从另一个项目中拖入了一些类文件,这些类文件是引发异常的文件。
hairbo

1
我从项目中删除了一个文件,然后稍后又添加了该文件,这解决了问题。
MindSpiker

70

这实际上与Interface Builder无关,这里发生的是Xcode并未从您的静态库中加载符号。要解决此问题,您需要将-all_load -ObjC标志添加到Other Linker Flags项目(可能还有目标)构建设置的键中。

由于Objective-C每个类仅生成一个符号,因此我们必须通过使用-ObjC标志来强制链接器也加载类的成员,并且还必须通过添加-all_load链接器标志来强制包含静态库中的所有对象。如果迟早跳过这些标志,将会遇到错误unrecognized selector或得到其他异常,例如您在此处观察到的异常。


5
我发现-ObjC仅凭旗帜就可以解决此问题。
Kekoa 2012年

5
@Kekoa,这是因为您的Xcode(LLVM)版本比编写此答案的人使用的版本新。如今,使用-ObjC足以解决问题。
直到2012年

这只会帮助我。在编译过程中,它显示了与框架相关的必要问题,当我导入所有框架后,这些问题也得以解决。
Vaibhav Saran

-ObjC标志独自解决了我的问题。我实际上在iOS7中具有all_load属性时出错。
Sushma Satish 2014年

使用-all_load -ObjC可能会导致不必要的产品尺寸增加。仅在框架中,类别文件也会发生此问题。
阿里·阿敏

26

我今天确实使用Swift遇到了这个问题。

我把班级Model.h + Model.m改为了Model.swift。该对象在Interface Builder中与一起使用class = Model

一旦替换了对象,就无法再加载该类。

我要做的是将IB中的类引用从:

Class = Model
Module = 

Class = Model
Module = <TARGETNAME>

您会<TARGETNAME>在构建设置中找到。它也是显示在您生成的Swift-Header中的名称:#import "TARGETNAME-Swift.h"


1
这似乎是正确的答案。除非有人可以说,否则应将其标记为正确。
比昂·罗斯伯格(BjørnRuthberg)

1
很好的回答,谢谢。对我来说,Module名字就在下拉列表中。这是我的应用程序的名称。
ChrisH

这个对我有用。对于我的问题,答案中提到的<TARGETNAME>是包含类的框架名称。
泰勒·朗

我自己得出结论,这也是我遇到的错误,并且当我看到您的帖子时愿意发表我的发现。实际上,我看到了它,但由于它有很多答案和周围的噪音,它还是通过了。我认为您可以通过一些屏幕截图来改善您的答案,以区别于其他答案。如果是这样,我一定会抓住的。无论如何,非常感谢您在此处发布它。你得到我的支持。
jvarela

对于AppDelegate,我能够在Interface Builder UI中解决此问题。对于窗口中UI元素的自定义类,Interface Builder UI不允许我设置自定义类和模块。我必须执行以下操作:(1)打开.xib文件作为“源代码”(右键单击它)。(2)在customClass属性旁边添加属性“ customModule = <TARGETNAME>”。
Poulsbo

20

转到“ ProjectName”,单击它,然后转到“ Build phases”选项卡,然后单击“ compile sources”,然后单击“ +”按钮,将出现一个窗口,选择“ MyClass”。 m”文件,然后单击“添加”,

构建项目并运行它,问题一定会得到解决


是的,我没有检查所有想要添加到新导入的类中的目标框。谢谢!
乔尔·巴尔默

是! 目标项目中缺少我的VC文件。
塞巴斯蒂安·德沃尼克

19

这是Xcode4缓存问题,只需删除/ Users / your_user / Library / Application Support / iPhone Simulator / 4.3 / Applications /下的所有文件夹

另外,如果您在iPhone上进行相同的问题测试,请在运行之前删除旧应用...

祝好运。Pascual


8
在项目构建设置中,需要将“ -all_load -ObjC”标志添加到“其他链接器标志”键。这不是Xcode 4特有的问题,实际上通常也与Interface Builder无关。
阿拉斯戴尔·艾伦

已经在2010年1月提出了该解决方案的建议(请参见上文)。
jhoule,2011年

6
是的-更简单的方法是打开iOS模拟器,然后从菜单中选择“重置内容和设置”
RanLearns 2011年

或者,您可以执行我的操作,然后从模拟器主屏幕中删除有问题的应用程序。我有相同的错误消息,但它引用的是旧的应用程序委托。
spstanley

16

有时IBuilder错过了 customModule="AppName" customModuleProvider="target"

要解决此问题,请打开情节提要作为源代码并替换以下行:

<viewController storyboardIdentifier="StoryboardId" id="SomeID" customClass="CustomClass"
sceneMemberID="viewController">

对此:

<viewController storyboardIdentifier="StoryboardId" id="SomeID" customClass="CustomClass"
 customModule="AppName" customModuleProvider="target" sceneMemberID="viewController">

一旦我运行Xcode 6.3(6D570),设置就会恢复为原始(错误)设置。虫子?我正在尝试在Objective C项目中包含一个快速文件。
addzo

在XCode 6.4上,只需在所需的viewcontroller下的情节提要源代码中添加customModuleProvider =“ target”,即可解决此问题。
Amro Shafie

我用just就能解决我的问题customModule="MyFrameworkName"。巨大的+10
Stan

实际上,我的问题恰恰相反,我想删除CustomTaget,但Xcode并未更改xib源文件,因此我必须删除customModule =“ AppName” customModuleProvider =“ target”才能使其正常工作。
Adriana

14

我的情况-在我的目标C项目中尝试使用swift框架中的Class时,出现此错误。解决方案是在“界面构建器/情节提要”中添加该类的模块(交换框架),如下所示。没有其他的

在此处输入图片说明


2
我在CocoaPods安装的Swift项目中使用Swift框架。此方法有效。模块名称是框架的名称。
JsW

1
这是完美的作品。需要为什么删除该模块?
iSrinivasan17年

与cocoapod框架问题完美配合...为您提供完美答案而
感到荣幸

13

转到构建阶段->编译源,然后添加新的.m文件。


是的,在将以前项目中的新文件添加到XCode 4.5项目中之后,将.m文件添加到“编译源”列表中就可以确定完成了。在我的情况下,添加“ -all_load -ObjC”不起作用,但是也没有受到伤害。
whyoz 2012年

13

以我为例,它显示的是甚至根本不存在的类的错误!我怀疑这是情节提要文件中令人讨厌的东西。如果您无法在错误中识别类文件,请尝试以下操作:

1)在Sublime或其他好的编辑器中打开您的项目。搜索要引用的类。2)删除整个说

customClass="UnrecognizedClassName"

3)保存。4)返回到xcode并清理项目,然后立即尝试运行它。

为我工作。

在此处输入图片说明


我使用OSX TextEdit应用程序。对于此操作,它工作正常。确保先关闭项目并关闭Xcode。
TJ 2014年

那也有帮助。我有多个具有相同customClass的对象,我可能单击了视图而不是单击控制器,并分配了相同的名称。
Mc

1
这也是我遇到的问题的解决方案。我以前输入的是部分班级名称,因此以某种方式保存情节提要(例如customClass="MyCla")。我不删除自定义类的分配,而是谨慎地将其放在我最初打算使用的类中:)
dave 2014年

9

我只想添加此答案,因为此处大多数(如果不是全部)答案都假定该类确实存在。.只是链接器/编译器太笨而看不到..因此答案围绕着提醒链接器存在的方式展开类或创建黑客来“强迫”存在。

当此消息实际上是在谈论一个不存在的类时,我的问题就发生了。所以一个例子是我回到不知道某个类的旧git修订版。但是编译器抱怨说该类没有不存在

解?

  • NUKE整个事情!首先删除所有构建文件,等等,方法是删除此目录中的所有内容〜/ Library / Developer / Xcode / DerivedData
  • 从手机本身删除应用(如果您使用模拟器,请清除模拟器内容)

那之后你应该很好


2
无法对此+1足够,解决了我的问题。我的问题与文件已被删除但编译时仍然出现警告的情况完全相同。
Brett 2013年

在情节提要中,您必须填写标识符。有时,我会错误地将其写在“类”字段(在Identity Inspector中)中。因此,编译器抱怨该类不存在!
文森特

9

消除错误的最佳方法是: 1)选择类文件(.m) 2)在“ 目标成员身份 ”下,“检查”项目名称条目


这可行。我正在开发一个pod,由于某种原因,pod install命令将错误的目标应用于一个特定的类文件。它被应用于我拥有的资源包。正确的配置是Pods- <project-title>-<pod-title>
krosullivan 2014年

这对我不起作用。目标成员身份正确,但是错误不断发生。
Kokodoko

8

我通过从class.h和.m复制文本,从项目中删除这些类文件并使用“添加文件”创建具有相同名称的新class.h和.m文件来解决此问题。然后,我将代码重新粘贴到新文件中,一切正常。创建文件时,文件以某种方式未正确链接。在那之后,我不需要使用任何链接器标志。


1
当我第一次创建文件时,最后没有.m。我尝试重命名文件并将其重新添加回去,但是在xcode满意之前,我仍然必须删除并重新创建文件。
2011年

您的文件可能不属于目标。重新添加它可能最终在正确的目标中带有默认复选框。
jhoule 2011年

1
此解决方案也对我有用,但是我100%确保在删除第一类(.h + .m)之前,我检查它是否是我的目标的一部分。这对我来说不是问题。像劳拉一样,我只是删除了该类,然后再次将其重新命名(使用不同的名称),并且在此页面上没有任何其他解决方案的情况下,它运行良好。
奈特

7

我终于解决了这个问题,我忘记将以下代码添加到我的.m文件中:

@implementation MyTableViewCell

@end

造成这种情况的原因是因为我为表格单元格创建了一个占位符@interface,该占位符与.xib文件中的元素具有连接,但是Interface Builder中存在一个错误,即如果没有为类指定@implementation,它找不到。

我已经完成了其他论坛的所有步骤,即使我已经从代码中注释掉了.xib作为源并看到MyTableViewCell。我试图重置模拟器。我什至尝试将我所有的类分解为与接口名称相同的单独文件,但在此之前没有任何作用。

PS,根据我的经验,.h / .m文件的名称是否与@interface的名称不同并不重要。我有几个文件包含多个@interface,它们工作正常。

PPS我在https://stackoverflow.com/a/22797318/539149上有UITableViewCell和UICollectionViewCell为什么导致此错误的更详细说明,以及如何在编译时使用registerClass:forCellWithReuseIdentifier:揭示此错误。


6

发生这种情况是因为.xib具有到旧的App Delegate的陈旧链接,该链接不再存在。我这样修复它:

  • 右键单击.xib,然后选择“打开为”>“源代码”
  • 在此文件中,搜索旧的应用程序委托并将其替换为新的

作为源代码打开不再存在,但是您可以轻松地右键单击,在Finder中显示,然后右键单击该文件,然后在TextEdit中打开。当然,在进行任何更改之前,请备份文件;)
Scott Allen

6

只需在appdelegate applicatoindidfinishlanching方法的开头添加以下代码,即可正常工作

[myclass类];


5

我尝试了此站点上列出的其他答案,但都没有为我排序。此评论(来自http://www.iphonedevsdk.com/forum/iphone-sdk-development/43330-unknown-class-interface-builder-file.html)有助于:

经过搜索和搜索之后,我终于找到了隐藏在文件中的已删除类的名称。我必须用X代码打开界面生成器文件,方法是右键单击它们,然后选择“查看作为源代码”。然后寻找它想出了

<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchP lu gin</string>
<string>*this was the class name*</string>

仅仅删除最后一行并不能解决它,不幸的是,抱怨文件中项目数量错误。您需要在其上方的行部分中删除相应的行,即CustomClass


5

就我而言,我有XCode6,指定的class .m文件在生成阶段中位于错误的位置-它应该在Compile Sources下,但最终在复制捆绑资源


感谢您,我开始查看列表,发现文件丢失了,可能是在创建文件时我没有正确设置目标
schmru


4

这个问题似乎不会过时。

我在Xcode 8中遇到了同样的问题,并像smilebot一样解决了它:

  1. 在Xcode中以“源代码”打开情节提要文件:

  2. 搜索要引用的类并删除整个内容

customClass =“ UnrecognizedClassName”

  1. 再次以“ interfacebuilder-Storyboard”的形式打开您的故事板文件,然后重新构建您的应用程序。

3

只需删除MyClass.m和.h并将它们再次添加到项目中对我来说是可行的。


3

我有“ Interface Builder文件中的Unknown class favouritesButton”,并将其追溯到一个故事书场景,其中该按钮在Identity Inspector顶部的“类”字段中具有虚假的自定义类“ favouritesButton”。我打算将该值放在下一个字段中:身份标签。

将此更改为“ UIButton”即可解决问题。



1

今天,在将我的aaLuminate应用程序转换为Xcode 4下的Universal时,出现了这个错误。该应用程序基于实用程序模板,最初是在Xcode 3下构建的。

为了节省时间,我将iPhone主视图和Flipside视图复制到通用应用程序上的相应名称中。我遇到了“ Interface Builder文件中的未知类x”错误。就我而言,XIB文件或目标中没有任何内容。

我还出于其他原因复制了aaLuminate-Info.plist文件-这有一个旧键“ Main nib file base name”设置为MainWindow。

一旦删除此密钥,它就解决了问题!


1

就我而言,出现此错误是因为我试图通过创建一个新项目然后删除一些源文件并从工作项目中复制相同名称的源文件来保存一些工作。我还复制了正在寻找RootViewController的MainStoryBoard文件。但是,当我删除了原来的RootViewController并从以前的产品中添加到RootViewController时,显然“添加文件”操作无法如上所述“选中”目标框。通过仅查看所有newley导入的“ .m”文件并确保已选中目标成员资格框,一切都很好。我认为正在发生的事情是故事板文件正在寻找一个由于未选中目标成员资格而从链接中“排除”的类。确保在文件检查器的目标成员身份中如此指定了目标所需的文件,从而达到了目的。谢谢帕特!(往上看)


1

就我而言,这是因为我在.h文件中声明了UITableView单元的子类的子类(两个子类的声明都在同一个.h文件中),但是却忘记了在.m文件。

不要忘记实现在.h文件中声明的子类的任何子类!听起来很简单,但很容易忘记,因为如果您在每个.h / .m文件中使用一个类,则Xcode会为您执行此操作。


1

我有“接口生成器中的未知类RateView”,其中RateView是UIView的子类。我已经将UIView放到Storyboard场景上,并将Custom类字段更改为RateView。仍然出现此错误。

为了进行调试,我将类的名称更改为RateView2,并将所有引用更改为匹配,除了UIView的“自定义类”字段。错误消息仍然像以前一样出现,RateView作为缺少的类。这确认该错误消息与“自定义类”字段的值有关。我将此值更改为RateView2,错误消息更改为“ Interface Builder中的未知类RateView2”。各种进展。

最后,我在文件检查器中检查了源代码文件本身。在那里,我发现源代码文件(是从教程中复制的)与我的Target无关。换句话说,它没有目标成员身份。我选中了使该类的源代码文件成为目标应用程序成员的框,并且错误消息消失了。


1

在我的情况下,我删除了一个名为“ viewController”的类,但没有意识到它是由情节提要的身份检查器选择的(在顶部的“自定义类”下)。

您只需在身份检查器的“自定义类”字段中为视图控制器选择正确的类,或向您的项目中添加一个新类,然后选择该类作为“自定义类”即可。

为我工作!



1

这让我有点发疯,上面的建议都没有帮助我摆脱错误。幸运的是,我使用该类只有一个IB对象,因此我将其删除并使用指定的相同类将其添加回去。错误消失了...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.