在Swift中动态创建对象

3

在 Objective-C 中我有一个分类:

@implementation NSObject (Entity)
+ (instancetype)entity{
    Class cl = self.class;
    NSObject *obj = [[cl alloc] init];

    return obj;
}
@end

假设有A类和B类:

@interface A : NSObject
@end

@interface B : NSObject
@end

然后我可以使用静态entity方法创建对象,例如:

NSObject *o = [NSObject entity]; // type of NSObject
A *a = [A entity];               // type of A
B *b = [B entity];               // type of B

我该如何在Swift中写出这个类别?我知道,如果了解类型,可以创建一个对象,例如let s = NSString.self; var str = s.init(),但在这里我不知道类别,应该是类似于self.self的东西,但它没有意义并且肯定无法工作。

提前致谢。


这个问题至少与你的类似。 - Adam
3个回答

5
let s = NSString.self;
var str = s.init();

如果您需要这个类,只需要:
print(s) // "NSString"

s是"NSString.Type"类型的,它代表了Object类;

如果你需要一个对象的类,我认为你要搜索的是"dynamicType":

let object = "toto"
let t = object.dynamicType // String.Type

var newObject = t.init("toto");

3
正如其他人提到的,整个重点在于Objective-C为所有类提供了基类,而Swift没有。 obj-C中的NSObject提供alloc和init方法,因此可以期望从NSObject继承的子类将实现或继承这些方法,因此您可以像您在问题中提到的那样使用快捷方式-类别。
在Swift中没有基类,因此您无法知道哪个类(或其他类型)提供了哪些初始化程序。不管怎样,您都必须为您的目的指定它们,我认为协议是最好的方式。
例如,请考虑以下内容:
protocol DefaultInstantiatable {
    init()
}

extension DefaultInstantiatable {
    static func entity() -> Self {
        return Self()
    }
}

如果您的类型采用了 DefaultInstantiatable 协议,那么您可以使用以下语句:
struct Foo: DefaultInstantiatable {
    init() { }
}

class Bar: DefaultInstantiatable {
    required init() { }
}

let foo = Foo.entity()  // Creates an instance of Foo structure
let bar = Bar.entity()  // Creates an instance of Bar object

我无法让 return Self() 正常工作。Xcode 7.3.1 报语法错误。 - Chris Prince
它应该可以工作。在你的情况下出现错误肯定有原因。请为此创建一个单独的问题。 - 0x416e746f6e
啊!我的错!我刚从你这里学到了一些很酷的东西——我之前没有看到这是在协议扩展的上下文中。我喜欢这个!我之前只是试图在一个方法中通用地尝试return Self(),但那并不起作用。 - Chris Prince

2

正如我在评论中提到的那样,原因是Swift中没有基类。你仍然可以通过实现自己的基类或者继承NSObject来实现。

class A : NSObject {}
class B : NSObject {}

extension NSObject {
    class func entity() -> Self {
        return self.init()
    }
}

A.entity()
B.entity()

NSObject.entity()

“dynamicType”不够吗? - LastMove
dynamicType 不允许您创建一个通用类别,这正是 OP 所要求的。 - Adam

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