【问题标题】:Swift – "Cannot find object class with name"斯威夫特 - “找不到具有名称的对象类”
【发布时间】:2014-06-14 00:10:05
【问题描述】:

我是 Cocoa 编程的新手,从未接触过 Objective-C。现在,我正在尝试通过阅读 Aaron Hillegrass 的书“Cocoa Programming for Mac OS X, 4e”来学习 Swift,并在 Swift 而不是 Obj-C 中实现所有内容。到目前为止一切顺利,但我成功了第 8 章中的障碍(RaiseMan 应用程序)。

这是书中的 Objective-C 代码:

标题:

#import <Foundation/Foundation.h>

@interface Person : NSObject {
    NSString *personName;
    float expectedRaise;
}
@property (readwrite, copy) NSString *personName;
@property (readwrite) float expectedRaise;
@end

这是实现

#import "Person.h"

@implementation Person

@synthesize personName;
@synthesize expectedRaise;

- (id)init
{
   self = [super init];
   if (self) {
      expectedRaise = 0.05;
      personName = @"New Person";
   }
   return self;
}

@end

然后你应该去 Interface Builder,获取一个数组控制器,指定 Person 作为它的类,并添加 personName 和 expectedRaise 作为它的键。

我在 Swift 中重写了 Person 类如下:

import Cocoa

class Person: NSObject {
    var personName = String()
    var expectedRaise = Float()
}

并按照书中的说明将其连接到 ArrayController。

Document文件中也有一些代码:

init() {
    employees = NSMutableArray()
    println("hi")
    super.init()
    // Add your subclass-specific initialization here.
    var p = Person()
    p.personName = "New Person"
    p.expectedRaise = 0.05                               
}

这是界面的样子(所以不会让我直接发布)https://www.dropbox.com/s/e5busxes9ex3ejd/Screenshot%202014-06-13%2019.02.37.png

当我尝试运行应用程序并单击“添加员工”按钮时,我在控制台中收到此错误:

“RaiseMan[9290:303] 找不到名为 Person 的对象类”

所以,我的问题是:我做错了什么?

【问题讨论】:

  • +1 因为和我有完全相同的问题!从 2008 年开始,我以为我用这本书在 Swift 中编写 Cocoa 应用程序是疯了。我知道我不是唯一一个以艰难的方式学习好东西的人。

标签: macos cocoa swift


【解决方案1】:

简答:需要在Interface Builder中指定类命名空间(模块名):RaiseMan.Person


详细信息和其他选项:

这是因为 Swift 为注入到 Objective-C 运行时的每个类的名称添加了一个前缀,以避免名称冲突。前缀遵循以下约定:_TtC$$AppName%%ClassName,其中$$AppName 的长度,%%ClassName 的长度(有关详细信息,请参阅 this other SO question )。

因此,为了使数组控制器能够实例化 Person 类,您需要在 Interface Builder 中提供损坏的名称:_TtC8RaiseMan6Person

另一种选择是使用 @objc(&lt;#name#&gt;) 属性为您的 Swift 类提供明确的 Objective-C 名称:

@objc(Person)
class Person: NSObject {
}

在这种情况下,您可以将 @objc 属性中指定的名称提供给 Interface Builder(例如 Person)。有关详细信息,请参阅Using Swift with Cocoa and Objective-C 指南。

【讨论】:

  • 这也适用于 Cocoa 绑定。在那里,您必须在 Object ControllerClass Name 字段中添加模块/命名空间名称。
  • 我自己也面临这个问题......长期的 iO​​S 开发人员,但对 Cocoa 完全陌生。我确实使用显式的 Obj-C 类名修复了它,但第一种方法看起来更干净,所以我想弄清楚。请在 IB 中的哪个对象上设置这个?我一直在尝试将它设置在不同的位置(数组控制器、表格列),但 Xcode 会立即删除我设置的任何内容...谢谢!
  • 在 Xcode 7.2/OSX 10.10.5 下,我的 My_App.ClassName 运气不佳,但 @objc 变体确实很好用。就像一个数据点。
  • 我必须使用明确的 Objective-C 名称才能使其工作
【解决方案2】:

如果我正确阅读了您的示例,并假设您的 init() 方法属于 Person 类,则需要将 init() 方法放在类大括号中。

另外,使用以下格式声明某种类型的变量:

var/let(名称):(类型)(可选)

因此,对于您的示例,您将改为使用 Person 类:

class Person {
    var personName: String
    var expectedRaise: Float?
    init() {...}
}

如果你不需要,你不一定非得从 NSObject 子类化;在 Swift 对象中,如果不需要,则不必从 NSObject(或另一个父对象)继承。还有“浮动”?表示它是 Optional Float 类型,这意味着它是一个可能有值的浮点数,也可能没有值,这取决于该人是否期望得到加薪(或者您可能不希望它是可选的,只是将值设置为 0)。

【讨论】:

  • 我今天早上实际上重写了我的 Person 类,现在它有了一个初始化程序,但问题仍然存在。
  • 你能发布你重写的 Person 类吗?还有你如何声明它的一个实例?
【解决方案3】:

请记住,如果您有多个构建目标,则您创建的每个新类都需要添加到该构建目标中。如果您没有将其目标成员资格设置为构建目标,Swift 将找不到类文件。

【讨论】:

    猜你喜欢
    • 2017-07-22
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 2017-11-13
    相关资源
    最近更新 更多