Ios 在具有public init的类中,在swift 4中创建单例

Ios 在具有public init的类中,在swift 4中创建单例,ios,swift,singleton,swift4,init,Ios,Swift,Singleton,Swift4,Init,我有一个不同代码的公共类,如下所示- public class Person { public required init() {} } 此类位于框架中,无法修改 现在的问题是我被告知从这个类继承并创建新类的单例对象 public class Jon: Person { public static var shared: Jon = Jon() required init() {} } 但是所需的init允许用户创建Jon类的多个实例 在swift 4中,有谁能建议

我有一个不同代码的公共类,如下所示-

public class Person {

   public required init() {}

}
此类位于框架中,无法修改

现在的问题是我被告知从这个类继承并创建新类的单例对象

public class Jon: Person {
    public static var shared: Jon = Jon()
    required init() {}
}
但是所需的init允许用户创建Jon类的多个实例


在swift 4中,有谁能建议如何做到这一点。

一个解决方案是使用组合而不是继承作为设计解决方案。由于Person对象也应该是单例对象,因此我们将其设置为不可变的,并使用所需的init在private
init
方法中对其进行初始化

public class Jon {
    static let instance = Jon()
    private init() {
        person = Person()
    }

    public let person: Person
}
它可以这样使用(例如,使用
名称
属性)

或者可以将Person设置为私有,并将计算属性添加到singleton类中

public class Jon {
    static let instance = Jon()
    private init() {
        person = Person()
    }

    private let person: Person

    var name: String? {
        get { return person.name }
        set { person.name = newValue}
    }
}
然后直接访问name属性

var jon = Jon.instance
jon.name = "John"

我找到了实现这一目标的解决方案。研究一下我的解决方案,希望它能达到你的目的

public class ParentClass {

    public required init() {}

}




class SubClass: ParentClass {

    static let sharedInstance = SubClass(foo: "")

    @available(*, unavailable)
    required init() { }


    //You can change the init parameter as per your requirement
    private init(foo: String) {
        super.init()

        //Write your initialization code
    }
}
如果你不想把任何参数传递给init,你可以这样做

private init(_ foo: String? = nil) {
        super.init()

        //Write your initialization code
}
现在,您可以在不传递任何参数的情况下初始化对象,如

static let sharedInstance = SubClass()

你能从
Person
中去掉
必需的
关键字吗?否则就不可能在子类中重写所需的初始值设定项。我认为最好的方法是将所需的init
设置为internal
。已添加到Swift 4.2中:
公共类现在可能具有内部必需的初始值设定项。
但internal关键字仅表示您无法从其他模块访问此方法的内容,据我所知,这不是我们的情况。如果你因为在另一个模块中访问它的人可以初始化
Person
而将其私有化而开枪,那么至少使用
内部
可以实现这一点。如果您还需要保护您的模块不调用
init
,那么是的,使用
internal
将无法实现这一点。另一种方法是将
guard Jon.shared==nil else{fatalError(“use Jon.shared”)}
添加到
init
以防止另一个实例的实例化。
static let sharedInstance = SubClass()