在Swift中动态创建对象

时间:2015-09-21 09:38:57

标签: ios objective-c macos swift introspection

在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那样没有任何意义并且无法确定

提前致谢

3 个答案:

答案 0 :(得分:5)

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

如果你需要上课,那就是:

print(s) // "NSString"

的类型为“NSString.Type” 它代表Object类;

如果你需要一个对象的类,我认为你正在搜索“dynamicType”:

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

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

答案 1 :(得分:3)

正如其他人所提到的,重点是Objective-C为所有类提供基类,而Swift则没有。 obj-C中的NSObject提供allocinit方法,因此可以预期来自NSObject的后代将实现或继承这些方法,因此您可以拥有快捷方式您在问题中提到的类别。

在Swift中没有基类,因此您无法知道哪个类(或其他类型)提供了哪些初始化程序。无论如何,您都必须根据自己的需要指定它们,我认为协议是最好的方法。

E.g。考虑一下:

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

答案 2 :(得分:2)

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

来实现
class A : NSObject {}
class B : NSObject {}

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

A.entity()
B.entity()

NSObject.entity()