【问题标题】:Create objects dynamically in Swift在 Swift 中动态创建对象
【发布时间】:2015-12-17 22:58:28
【问题描述】:

在 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 之类的东西,它没有任何意义,而且肯定不能工作。

提前致谢

【问题讨论】:

标签: ios objective-c macos swift introspection


【解决方案1】:
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");

【讨论】:

    【解决方案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”还不够吗?
    • dynamicType 不允许您创建通用类别,这是 OP 要求的。
    【解决方案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 出现语法错误。
    • 它应该可以工作。一定有一些原因导致它在您的情况下出错。请为此创建一个单独的问题。
    • 啊啊啊!我的错!我刚刚从你那里学到了一些很酷的东西——我没有看到这是在 protocol 扩展的上下文中。我喜欢!我只是一般地尝试在一个方法中return Self(),但这不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    相关资源
    最近更新 更多