Синглтон со свойствами в Swift 3


88

В документе Apple « Использование Swift с Cocoa и Objective-C» (обновленном для Swift 3) они приводят следующий пример шаблона Singleton:

class Singleton {
    static let sharedInstance: Singleton = {
        let instance = Singleton()

        // setup code

        return instance
    }()
}

Представим, что этот синглтон должен управлять переменным массивом строк. Как / где мне объявить это свойство и убедиться, что оно правильно инициализируется пустым [String]массивом?

Ответы:


236

Для меня это лучший способ сделать init приватным. Синтаксис Swift 3 \ 4 \ 5

// MARK: - Singleton

final class Singleton {

    // Can't init is singleton
    private init() { }

    // MARK: Shared Instance

    static let shared = Singleton()

    // MARK: Local Variable

    var emptyStringArray = [String]()

}

4
Я поддержал этот ответ, но для соответствия синтаксису Swift 3 «sharedInstance» следует заменить на «shared».
B-Rad

1
Если не будет регресса от swift 2 к swift 3, то этого не
произойдет,

1
Тип после shared можно не указывать, верно? static let shared = Singleton()
Крисвиллоу

1
@YannickSteph, тебе не нужно писать, static let shared: Singleton = Singleton()ты можешь просто написатьstatic let shared = Singleton()
Крисвиллоу

3
@RomanN Нет, вы не можете переопределить init, потому что он не наследует класс. Если вы можете это сделать, на этом примере final class Singleton: NSObject { private override init() { } }
YannSteph

59

Вы можете инициализировать пустой массив следующим образом.

class Singleton {

    //MARK: Shared Instance

    static let sharedInstance : Singleton = {
        let instance = Singleton(array: [])
        return instance
    }()

    //MARK: Local Variable

    var emptyStringArray : [String]

    //MARK: Init

    init( array : [String]) {
        emptyStringArray = array
    }
}

Или, если вы предпочитаете другой подход, подойдет этот.

class Singleton {

    //MARK: Shared Instance

    static let sharedInstance : Singleton = {
        let instance = Singleton()
        return instance
    }()

    //MARK: Local Variable

    var emptyStringArray : [String]? = nil

    //MARK: Init

    convenience init() {
        self.init(array : [])
    }

    //MARK: Init Array

    init( array : [String]) {
        emptyStringArray = array
    }
}

Этот метод не работает в расширении? extension Cache { static let sharedInstance: Cache = { let instance = Cache() return instance }() }
Эндрю

1
Интересно, что Apple использует class varв iOS 10 для синглтонов (например, UIApplication). Будет ли их реализация такой же?
jjatie

2
Я предпочитаю одноэлементные методы инициализации , как privateметоды не даже internal. Это не позволяет другим использовать инициализатор по умолчанию '()' для этого класса.
Kumar C

1
@KumarC Вы правы, разве это не решит проблему, если мы добавим privateв init.

@TikhonovAlexander Не могли бы вы принести дополнительную информацию?
Dominique Vial

30

Согласно документации Apple: в Swift вы можете просто использовать свойство статического типа, которое гарантированно будет лениво инициализировано только один раз, даже при одновременном доступе через несколько потоков .

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()
}

С методом инициализации:

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()

    // MARK: - Initializer

    private init() {
    }

}

3
почему init () не закрытый?
XcodeNOOB

0

Любая инициализация будет выполняться в методе инициализации. Здесь нет разницы между синглтоном и не-синглом.


26
Дополнительный фрагмент кода, который напрямую отвечает на вопрос, сделает этот ответ более полезным.
Реда Лемеден,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.