Swift 中的“使用未声明的类型”,即使类型是内部的,并且存在于同一个模块中
Posted
技术标签:
【中文标题】Swift 中的“使用未声明的类型”,即使类型是内部的,并且存在于同一个模块中【英文标题】:"Use of undeclared type" in Swift, even though type is internal, and exists in same module 【发布时间】:2014-08-22 00:22:41 【问题描述】:我的模块中有一个类型:
import Cocoa
class ColoredDotView : NSView
...
它被用于许多不同的类中,没有问题:
class EditSubjectPopoverController : NSObject
@IBOutlet internal var subjectColorDotView : ColoredDotView!
...
但由于某种原因,当我在一个特定类中使用它时,我的类型出现编译错误:
class EditTaskPopoverController : NSObject
@IBOutlet internal var lowPriorityDotView : ColoredDotView! // Error here
@IBOutlet internal var medPriorityDotView : ColoredDotView! // And here...
@IBOutlet internal var highPriorityDotView : ColoredDotView! // And here...
...
编译错误是:
EditTaskPopoverController.swift:15:49:使用未声明的类型 '彩色点视图'
我不明白。这是文件中的第一个编译错误,其余的错误都是第一个的症状。此外,没有其他文件出现编译错误。我不明白为什么类型未声明,因为文件在同一个模块中:
我已经尝试清理项目,清理构建文件夹,并重新启动 Xcode,但无济于事。哪些潜在的失误会导致 Swift 中出现undeclared type
编译器错误?
【问题讨论】:
我遇到过很多实际错误是几行(或更多)的情况,并且 Xcode 错误地用错误消息标记了一些无害的东西。看看是否可以通过擦除其余代码来消除该错误,然后将其一点一点地添加回来... 感谢 Nate - 不幸的是,我删除了var
声明,然后开始构建。然后我在顶部添加 一个 声明,错误立即返回:imgur.com/VUUBK2K
【参考方案1】:
对我来说,当我的测试目标没有我的应用程序构建目标在编译源中具有的一些 swift 文件时,我遇到了这个错误。这非常令人困惑,因为“未声明的类型”在许多其他地方都没有问题地使用,而且错误似乎含糊不清。所以解决方案当然是将包含“未声明类型”的文件添加到测试目标中。
【讨论】:
似乎显示“未声明类型”的文件在测试目标中,但“未声明类型”不在测试目标中。所以它在测试目标环境中是未声明的类型。 请注意,您也可能缺少 @testable 导入。【参考方案2】:@Craig Otis 已经回答了这个问题,但是当有问题的类不属于相同的目标时,通常会丢失测试目标。只需确保勾选以下复选框即可。
编辑
查看目标成员资格。选择您的文件,然后打开文件检查器 (⌥ + ⌘ + 1) [option] + [command] + 1
【讨论】:
【参考方案3】:呼,终于诊断出来了。 不知何故,有问题的 Swift 文件 EditTaskPopoverController.swift
处于两个不同的构建阶段。
它正确地在Compile Sources
中,与所有其他 Swift 文件一起,但它也是也是,出于某种非常奇怪的原因,在Copy Bundle Resources
阶段以及我所有的 XIB和图片资源。
我不知道它是如何到达那里的,但是从额外的构建阶段中删除它解决了这个问题。
【讨论】:
【参考方案4】:在 XCode 菜单 Product->Clean 然后 Product->Build 为我工作。我在新组/文件夹中将新 ViewController 添加到我的项目时遇到了这个问题。
【讨论】:
【参考方案5】:我遇到了完全相同的问题。我框架中的某些文件无法从同一模块中的其他类访问。
由于某种原因,在 Xcode 中添加到框架的文件不是编译源的一部分。如果您的 Swift 文件不是编译源的一部分,您需要通过点击 + 并在弹出窗口中选择它们来添加它们。
还要确保文件是框架目标的一部分。 (下面截图中的小方框应该勾选)
【讨论】:
【参考方案6】:我的原因是函数名称以与类型相同的字符开头:
@IBOutlet weak var tableView: CustomTableView!
在实现中,我有一个以 CustomTableView
开头的函数func CustomTableView(tableView: CustomTableView, dataForRow row: Int) -> NSData ...
解决方法是更改函数签名,使其不以与类型 (CustomTableView) 相同的字符开头,例如:
func dataForRow(row: Int, tableView: CustomTableView) -> NSData ...
对于我的实际原因,这是一条非常具有误导性的错误消息。
【讨论】:
【参考方案7】:如果有人遇到类似的问题,但Compile Sources fix 没有解决问题,重新启动 Xcode 可能(它对我有用)。我的 Xcode 版本是Version 6.1 (6A1052d)
。
【讨论】:
重启对我有用,尽管在成功构建后再次弹出错误,没有任何进一步的代码更改。【参考方案8】:在我的应用程序中,我有应用程序委托和其他需要由测试公开访问的类。 As outlined here,然后我将我的应用程序导入到我的测试中。
当我最近创建两个新类时,它们的测试目标既是主要部分,也是测试部分。从测试中删除他们的成员身份解决了这个问题。
【讨论】:
【参考方案9】:在我的例子中,TestTarget 的编译源包含来自主目标的文件。
参考:
为什么会这样?
这是因为我们在创建时检查了 TestTarget 关联 文件
或从检查器手动检查此选项。
参考:
我是怎么解决的?
我从测试目标的编译源中删除了主要目标的文件【讨论】:
【参考方案10】:有时错误可能非常愚蠢
在检查所有解决方案之前,请确保您有 导入所有基本的东西
import Foundation
import UIKit
很有可能当你从外部导入一些文件时 到你的项目,这可能会错过我所经历的这些基本事情 一次。
【讨论】:
【参考方案11】:我尝试了这里提供的许多解决方案,但最终删除了该文件并重新创建了它,并且 Xcode 被安抚了:/
【讨论】:
【参考方案12】:如果您不小心将参数名称大写,并且将其命名为与对象相同的名称,也会发生这种情况。
class func didRecieveData(BlockItems: [BlockItems])
【讨论】:
【参考方案13】:这可能对某人有所帮助。
我使用名为“CoreData”的 Core Data 创建了新的测试项目。很快,我就有了 NSManagedObjectContext 和其他核心数据类的“使用未声明的类型”。经过多次尝试导入、添加到构建阶段等。我删除了项目并启动了一个名为“TestingCoreData”的新项目,一切都运行良好。
不要像类名那样命名(测试)项目
【讨论】:
【参考方案14】:如果您有一个与签名中的对象类型同名的函数,也会发生这种情况。例如:
class func Player(playerObj: Player)
将导致编译器感到困惑(这是理所当然的),因为编译器会先在文件中本地查找,然后再查看其他文件。所以它查看签名中的“Player”并认为,这不是这个范围内的对象,而是一个函数,所以有问题。
也许这是我不应该将类函数大写的一个很好的理由。 :)
【讨论】:
【参考方案15】:我在 Xcode 8 中将代码重构到框架中时收到此错误消息,结果我忘记在框架中将类声明为 public
【讨论】:
【参考方案16】:也许你已经添加了一些“FirstNameClass”的类,然后手动重命名为“ColoredDotView”。尝试将“ColoredDotView”类的内容复制到剪贴板,从项目中删除“ColoredDotView”并添加agin。
这个 id 解决了我的类似问题。
【讨论】:
【参考方案17】:就我而言,这是我犯的一个错误。我添加了一个新文件为“OS X>Source>Cocoa Class”,而不是“ios>Source>Cocoa Touch Class”。
【讨论】:
【参考方案18】:在我的例子中,这是由于在下一行中使用了一个子类名称作为具有不同类型的变量名称:
var binGlow: pipGlow = pipGlow(style: "Bin")
var pipGlow: PipGlowSprite = PipGlowSprite()
请注意,在第 1 行中,pipGlow 是(SKShapeNode 的)子类的名称,但在第 2 行中,我使用 pipGlow 作为变量名。这不仅是糟糕的编码风格,而且显然也是一个彻底的禁忌!一旦我将第二行更改为:
var binGlow: pipGlow = pipGlow(style: "Bin")
var pipGlowSprite: PipGlowSprite = PipGlowSprite()
我不再收到错误消息。我希望这对某人有帮助!
【讨论】:
【参考方案19】:在测试属于应用程序的 Swift 代码时,首先要确保测试目标将应用程序构建为依赖项。然后,在您的测试中,将应用程序作为模块导入。例如:
@testable import MyApplication
这将使作为应用程序一部分的 Swift 对象可用于测试。
【讨论】:
【参考方案20】:就我而言,这是由 swift 文件的文本编码引起的。 一个文件显示“无显式编码”,将其转换为“UTF-8”后,问题解决了。
文件的文本编码不明确的原因是我从其他swift文件中复制了所有代码。
无显式编码截图
UTF-8 截图
【讨论】:
【参考方案21】:清理项目解决了我的问题。
步骤: 产品 -> 清理(或 Shift + Cmd + K)
【讨论】:
【参考方案22】:在我的例子中,我想添加一个带有自定义 swift 对象作为类型参数的方法,并且我在参数中给变量的名称与自定义对象类名称完全相同
问题是这样的:
func moveBlob(**blob** : blob)
...code
粗体字符部分导致未声明类型的错误
【讨论】:
【参考方案23】:正如其他人在this thread中提到的那样
在“复制捆绑资源”中使用不需要的 swift 文件
【讨论】:
【参考方案24】:和其他人一样,是一些不相关的代码导致 @testable
出现故障。
在我的测试目标中有一个包含
的 Objective-C 头文件@import ModuleUnderTest;
我删除了这一行(因为实际上不需要导入),奇迹般地@testable
又开始工作了。
我只能追踪到这一点,但从我的项目中删除了所有内容并一点一点地添加它,直到它失败。最终我找到了问题的代码行。
【讨论】:
【参考方案25】:如果您从不同的module
或Target
访问它,那么您只需要它到public
它
【讨论】:
【参考方案26】:万一有人犯了我犯的同样愚蠢的错误......
我收到此错误是因为在重命名源文件时,我不小心从文件名中删除了.
,因此编译器将文件视为纯文本文件,而不是作为编译源。
所以我打算将文件重命名为
MyProtocol.swift
却不小心取了名字
MyProtocolswift
这是一个简单的错误,但并不是很明显这就是正在发生的事情。
【讨论】:
【参考方案27】:没有添加正确的导入声明也可能是一个明显的失误。对我来说,我只是省略了导入 PriorityUIKit。
【讨论】:
【参考方案28】:我的情况是我将一个新文件 XXView.swift 拖到项目中。并将 View 类型声明为 XXView 然后错误“使用未声明的类型....”。
我只是尝试将我的 XXView.swift 添加到它解决错误的测试目标中。 但我不希望我的 UI 类参与测试目标。
最后,我发现我的 ViewController 已经在测试目标中,这不应该发生。 (我认为因为我是通过 xctemplate 创建的 VC,所以它会自动包含在测试目标中)
我从测试目标中删除了视图控制器,然后我的 XXView 现在不需要添加到测试目标中了。
结论:确保所有相关文件也应取消选中测试目标。
【讨论】:
【参考方案29】:在这个错误上花了一个小时后,我发现模块文件重复了。删除多余的文件,shift+cmd+k 清理,错误消失。
【讨论】:
这可能是一个愚蠢的问题,但你能解释一下吗?重复的 swift 文件或重复的组等也会发生这种情况吗?它有效,但我更想了解它为什么有效,而不仅仅是接受它有效。顺便感谢您的解决方案! 在复制和粘贴过程中,您可能会意外复制文件夹、模块等。Xcode 中的所有内容都应该是唯一的。我想这就是原因【参考方案30】:就我而言,问题在于新的class
未被识别。我通过删除类并重新添加它解决了这个问题,但这次在创建新类时检查了Watch App Extension
选项。
请注意,我的应用程序中确实有一个 Watch 应用扩展程序。
【讨论】:
以上是关于Swift 中的“使用未声明的类型”,即使类型是内部的,并且存在于同一个模块中的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中声明任何类型的数组时使用未声明的类型“T”
Objective-C 库的 Swift “使用未声明的类型”