【问题标题】:Swift: write a function that allocates an instance of (any) classSwift:编写一个分配(任何)类实例的函数
【发布时间】:2016-01-14 14:35:33
【问题描述】:

我正在 Swift 中寻找与以下 Obj-C 代码等效的代码:

- newInstanceOf:(id)classRef {
    return [classRef new];
}

然后使用它:

id instance = [whatever newInstanceOf:NSArray.class]
[instance isKindOfClass:NSArray.class] == YES

我尝试过使用 Swift 模板:

func newSomething<T>(classRef:T.Type) -> T {
    return classRef()
}

我收到错误:error: 'T' cannot be constructed because it has no accessible initializers

【问题讨论】:

  • 我试图了解您为什么要这样做。 whatever[whatever newInstanceOf:NSArray.class]中代表什么,为什么newInstanceOf是实例方法而不是类方法?
  • 没有什么特别的原因,只是不想写一个使用Obj-C对象的C函数,更把事情搞糊涂了。我想做这个 f.ex。创建一个将类作为参数的通用对象工厂。
  • 目前还不清楚您要达到的目标。 [whatever newInstanceOf:NSArray.class]NSArray() 有何改进?为什么工厂方法是实例方法而不是类方法,就像我之前问的那样?
  • 您可以使用 NSArray.class 作为变量。 f.ex.: [self createInstanceOf:self.classThatWasDefinedAtRuntime] 其中 self.classThatWasDefinedAtRuntime 之前由第 3 方设置

标签: objective-c swift class instance


【解决方案1】:

您可以创建一个协议来充当可通过 void-argument 初始化程序初始化的对象的类型约束,然后将您选择的类型扩展到此协议。

protocol SimplyInitializable {
    init()
}

extension Int : SimplyInitializable { }
extension Double : SimplyInitializable { }
extension String : SimplyInitializable { }

struct MyStruct {
    var myInt : Int
    init() {
        myInt = 0
    }
}
extension MyStruct : SimplyInitializable { }

func newSomething<T: SimplyInitializable>(classRef: T.Type) -> T {
    return classRef.init()
}

/* Examples */
var a = newSomething(Int)
var b = newSomething(Double)
var c = newSomething("".dynamicType)
var d = newSomething(MyStruct)
var e = newSomething(a.dynamicType)

print(a.dynamicType) // Int
print(b.dynamicType) // Double
print(c.dynamicType) // String
print(d.dynamicType) // MyStruct
print(e.dynamicType) // Int

【讨论】:

  • 我注意到每个 'extension * : SimplyInitializable { }' 不包含任何实际代码,因为 init() 无论如何都存在于每个类中。有没有办法做到这一点,而无需为我希望使用的每个类添加“扩展名..”?
  • @bamalex 是的。我不知道有一种方法可以一次将几种类型扩展到同一个协议,不确定是否可行,但也许其他人可以提供帮助。
【解决方案2】:

实际上在 Swift 中,并不是所有的类都保证有一个 init() 初始化器。它可以与 NSObject 类一起使用,因为 NSObject 确实有这个要求。

func newInstanceOf<T:NSObject>(aClass:T.Type) -> NSObject
{ return aClass.init() }

let string = newInstanceOf(NSString)   // ""
let date   = newInstanceOf(NSDate)     // 2016-01-15 05:27:29 +0000

【讨论】:

  • 那么也许有一种方法可以形成定义的 (aClass:T.Type) 部分,以允许调用者执行以下操作: newInstanceOf(SomeClass as!SimplyInitializable)
猜你喜欢
  • 2017-05-02
  • 2020-01-07
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
  • 2021-10-02
相关资源
最近更新 更多