Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 正在传递类。在函数中键入_Swift_Design Patterns_Architecture_Overriding_Factory Pattern - Fatal编程技术网

Swift 正在传递类。在函数中键入

Swift 正在传递类。在函数中键入,swift,design-patterns,architecture,overriding,factory-pattern,Swift,Design Patterns,Architecture,Overriding,Factory Pattern,为一个项目使用覆盖系统,该项目有一个核心代码库,安装在带有子模块的客户端项目中,客户端特定的文件和覆盖位于其各自的项目中 这是一个有点复杂的设置,但以这种方式设置架构有商业原因-即,我们需要对核心项目进行更新,同时允许客户对特定视图、控制器、模型进行更改-因此,我们需要在每个客户的基础上尽可能多的灵活性 我用99%的工厂模式建立了一个覆盖系统。当我需要一个对象时,我通过调用: let factory = Factory() let object = try factory.getObje

为一个项目使用覆盖系统,该项目有一个核心代码库,安装在带有子模块的客户端项目中,客户端特定的文件和覆盖位于其各自的项目中

这是一个有点复杂的设置,但以这种方式设置架构有商业原因-即,我们需要对核心项目进行更新,同时允许客户对特定视图、控制器、模型进行更改-因此,我们需要在每个客户的基础上尽可能多的灵活性

我用99%的工厂模式建立了一个覆盖系统。当我需要一个对象时,我通过调用:

let factory = Factory()    
let object = try factory.getObject(named: "MyObject", ofType: MyObject.self)
如果存在覆盖,工厂将实例化该覆盖(例如:override_MyObject),否则将实例化默认值(MyObject)。现在我只能在工厂中对这些anyobject进行类型转换,以便它们能够运行init()。在这段代码中,我传递了一个泛型类型“T”,但我无法在此处使用T从getInstance强制转换:

let object = try getInstance(name: named) as? T
T是泛型类型,不具有MyObject实例所具有的init()方法。斯威夫特不允许我传入MyObject.self并引用as中的那个参数?铸造声明

这里是一个操场上的完整源代码。它现在完全起作用了,因为我说的是as?类型而不是使用T来强制转换对象。我需要能够使用传入getObject函数的类型来强制转换从getInstance返回的对象

救命啊!非常感谢您的帮助

//: Playground - noun: a place where people can play

import UIKit

protocol TestProt {
    func testMe() -> String
}

@objc(MyObject)
class MyObject: NSObject, TestProt {
    func testMe() -> String {
        return "Hello from Base"
    }
    required override init() {

    }
}

@objc(override_MyObject)
class override_MyObject: MyObject {
    override func testMe() -> String {
        return "Hello from Override"
    }
    required override init() {

    }
}

class Factory {

    let overridePrefix: String = "override_"

    private func getInstance(name: String) throws -> AnyClass {

        do {
            let object = try checkOverride(name)
            return object
        } catch {
            throw FactoryError.defaultError
        }

    }

    public func getObject<T>(named: String, ofType: T.Type) throws -> AnyObject {
        do {
            let object = try getInstance(name: named) as? MyObject.Type
            if let dynamicObject = object?.init() {
                dynamicObject.testMe()
                return dynamicObject
            } else {
                throw FactoryError.defaultError
            }
        }
        catch {
            throw FactoryError.defaultError
        }
    }

    func checkOverride(_ className: String) throws -> AnyClass {

        let overrideClassName = overridePrefix + className

        if let object = NSClassFromString(overrideClassName) {
            print("\(overrideClassName) does exist")
            return object

        } else if let object = NSClassFromString(className) {
            print("\(className) does exist")
            return object

        } else {
            print("\(overrideClassName) does not exist")
            throw FactoryError.defaultError
        }
    }

    enum FactoryError: Error {
        case defaultError
    }

}

let factory = Factory()
let object = try factory.getObject(named: "MyObject", ofType: MyObject.self)
object.testMe()
/:操场-名词:人们可以玩耍的地方
导入UIKit
协议测试保护{
func testMe()->字符串
}
@objc(MyObject)
类MyObject:NSObject,TestProt{
func testMe()->字符串{
返回“基地你好”
}
必需的重写初始化(){
}
}
@objc(覆盖对象)
类重写\u MyObject:MyObject{
重写func testMe()->字符串{
返回“Hello from Override”
}
必需的重写初始化(){
}
}
阶级工厂{
让overrideeprefix:String=“override\ux”
private func getInstance(名称:String)抛出->AnyClass{
做{
让对象=尝试检查覆盖(名称)
回波信号
}抓住{
抛出FactoryError.defaultError
}
}
public func getObject(名为:String,类型为:T.Type)抛出->AnyObject{
做{
让object=try getInstance(名称:named)作为?MyObject.Type
如果让dynamicObject=object?.init(){
dynamicObject.testMe()
返回动态对象
}否则{
抛出FactoryError.defaultError
}
}
抓住{
抛出FactoryError.defaultError
}
}
func checkOverride(uclassname:String)抛出->AnyClass{
让overrideClassName=overridePrefix+className
如果let object=NSClassFromString(overrideClassName){
打印(\(overrideClassName)确实存在)
回波信号
}如果let object=NSClassFromString(类名),则为else{
打印(\(类名称)确实存在)
回波信号
}否则{
打印(\(overrideClassName)不存在)
抛出FactoryError.defaultError
}
}
枚举工厂错误:错误{
案例默认错误
}
}
让工厂=工厂()
let object=try factory.getObject(名为“MyObject”,类型为:MyObject.self)
object.testMe()

<>代码>不确定你到底想达到什么目标,但是考虑重新评估你的解决方案,这真的是糟糕的代码。如果这是您试图实现的,那么这可能是您下面的解决方案

public func getObject<T: MyObject>(named: String, ofType: T.Type) throws -> AnyObject {
    do {
        let object = try getInstance(name: named) as? T.Type
        if let dynamicObject = object?.init() {
            dynamicObject.testMe()
            return dynamicObject
        } else {
            throw FactoryError.defaultError
        }
    }
    catch {
        throw FactoryError.defaultError
    }
}
public func getObject(名为:String,类型为:T.Type)抛出->AnyObject{
做{
让object=try getInstance(名称:named)作为?T.类型
如果让dynamicObject=object?.init(){
dynamicObject.testMe()
返回动态对象
}否则{
抛出FactoryError.defaultError
}
}
抓住{
抛出FactoryError.defaultError
}
}

<>代码>不确定你到底想达到什么目标,但是考虑重新评估你的解决方案,这真的是糟糕的代码。如果这是您试图实现的,那么这可能是您下面的解决方案

public func getObject<T: MyObject>(named: String, ofType: T.Type) throws -> AnyObject {
    do {
        let object = try getInstance(name: named) as? T.Type
        if let dynamicObject = object?.init() {
            dynamicObject.testMe()
            return dynamicObject
        } else {
            throw FactoryError.defaultError
        }
    }
    catch {
        throw FactoryError.defaultError
    }
}
public func getObject(名为:String,类型为:T.Type)抛出->AnyObject{
做{
让object=try getInstance(名称:named)作为?T.类型
如果让dynamicObject=object?.init(){
dynamicObject.testMe()
返回动态对象
}否则{
抛出FactoryError.defaultError
}
}
抓住{
抛出FactoryError.defaultError
}
}

为什么不将init添加到协议中?它极大地简化了事情,代码对于任何类型都是相同的

protocol TestProt {
    init()
    func testMe() -> String
}

class Factory {

    static public func getObject<T: TestProt>() -> T {
        return T();
    }
}

let object: MyObject = Factory.getObject()
let object: override_MyObject = Factory.getObject()
协议测试保护{
init()
func testMe()->字符串
}
阶级工厂{
静态公共函数getObject()->T{
返回T();
}
}
let对象:MyObject=Factory.getObject()
let对象:覆盖\u MyObject=Factory.getObject()

为什么不将init添加到协议中?它极大地简化了事情,代码对于任何类型都是相同的

protocol TestProt {
    init()
    func testMe() -> String
}

class Factory {

    static public func getObject<T: TestProt>() -> T {
        return T();
    }
}

let object: MyObject = Factory.getObject()
let object: override_MyObject = Factory.getObject()
协议测试保护{
init()
func testMe()->字符串
}
阶级工厂{
静态公共函数getObject()->T{
返回T();
}
}
let对象:MyObject=Factory.getObject()
let对象:覆盖\u MyObject=Factory.getObject()

那么您的视图、视图控制器和模型应该与init()方法有共同的协议。在您的情况下,必须将NSObject作为基类

在下面的解决方案中,我创建了一个名为BaseInitializable的协议,该协议由父类实现。看看getObject方法

import UIKit

protocol BaseInitializable: class {
    func testMe() -> String
    init()
}

@objc(Parent)
class Parent: NSObject, BaseInitializable {


    func testMe() -> String {
        return "Hello from Base"
    }

    required override init() {
        super.init()
        print("parent constructor called")
    }

}

@objc(override_Child)
class override_Child: Parent {
    override func testMe() -> String {
        return "Hello from Override"
    }

    required init() {
        super.init()
        print("child constructor called")

    }
}

@objc(override_Cousin)
class override_Cousin: Parent {
     override func testMe() -> String {
        return "Hello from cousin Override"
    }

    required init() {
        super.init()
        print("cousin constructor called")

    }
}

class Factory {

    let overridePrefix: String = "override_"

    private func getInstance(name: String) throws -> AnyClass {

        do {
            let object = try checkOverride(name)
            return object
        } catch {
            throw FactoryError.defaultError
        }

    }

    public func getObject<T: BaseInitializable>(named: String, ofType: T.Type) throws -> AnyObject {
        do {
            let object = try getInstance(name: named) as? BaseInitializable.Type
            if let dynamicObject = object?.init() {
                dynamicObject.testMe()
                return dynamicObject
            } else {
                throw FactoryError.defaultError
            }
        }
        catch {
            throw FactoryError.defaultError
        }
    }

    func checkOverride(_ className: String) throws -> AnyClass {

        let overrideClassName = overridePrefix + className

        if let object = NSClassFromString(overrideClassName) {
            print("\(overrideClassName) does exist")
            return object

        } else if let object = NSClassFromString(className) {
            print("\(className) does exist")
            return object

        } else {
            print("\(overrideClassName) does not exist")
            throw FactoryError.defaultError
        }
    }

    enum FactoryError: Error {
        case defaultError
    }

}

let factory = Factory()
let object = try factory.getObject(named: "Child", ofType: Parent.self) 
object.testMe()
导入UIKit
协议BaseInitializable:类{
func testMe()->字符串
init()
}
@objc(母公司)
类父对象:NSObject,BaseInitializable{
func testMe()->字符串