2016-04-29 2 views
5

Как я могу избежать повторения кода между моими инициализаторами? Я хочу, чтобы dateFormatter оставался константой let.Swift избежать повторения кода в инициализаторе

let dateFormatter: NSDateFormatter 

init() { 
    dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    super.init(nibName: nil, bundle: nil) 
} 

required init?(coder aDecoder: NSCoder) { 
    dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    super.init(coder: aDecoder) 
} 

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
    dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
} 

ответ

9

Если это действительно фактический код заменить весь код с

lazy var dateFormatter : NSDateFormatter = { 
    let formatter = NSDateFormatter() 
    formatter.dateStyle = .MediumStyle 
    formatter.timeStyle = .MediumStyle 
    return formatter 
}() 

переменная лениво инициализируется один раз, когда он доступен в первый раз

Edit: Кроме того, можно объявить переменную как постоянный без ленивого атрибута.

let dateFormatter : NSDateFormatter = { ... 

Разница заключается в том, что форматировщик создается немедленно (не лениво) во время инициализации экземпляра.

Edit:

В Swift 3 NSDateFormatter был переименован в DateFormatter
и .MediumStyle к .mediumStyle

+1

, поскольку это будет ленивый, вам необходимо добавить здесь ленивый префикс? и изменить let to var. в противном случае логика форматирования даты не будет генерироваться мгновенно, а вместо этого будет вызвана каждый раз, когда к ней обращаются. –

+1

Нет, вы можете использовать обе формы, я просто тестировал ее на игровой площадке. – vadian

+0

'ПРИМЕЧАНИЕ Вы всегда должны объявлять ленивое свойство как переменную (с ключевым словом var), поскольку ее начальное значение не может быть получено до завершения инициализации экземпляра. Константные свойства всегда должны иметь значение до завершения инициализации и поэтому не могут быть объявлены как ленивые. ' [Источник] (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html) – Laffen

0

Это единственный способ, которым я мог думать:

class Sample: UIViewController { 
    let dateFormatter: NSDateFormatter = NSDateFormatter() 

    init() { 
     super.init(nibName: nil, bundle: nil) 
     setupDateFormatter() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setupDateFormatter() 
    } 

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     setupDateFormatter() 
    } 

    private func setupDateFormatter() { 
     dateFormatter.dateStyle = .MediumStyle 
     dateFormatter.timeStyle = .MediumStyle 
    } 
} 
+0

Я ценю ваш ответ. Я редактировал свой пост, если вы заинтересованы. –

3

В этом случае вы можете set the default property value of the date formatter using a closure.

Тогда ваше объявление собственности становится:

let dateFormatter: NSDateFormatter = { 
    let dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    return dateFormatter 
}() 

и вы можете удалить форматере бит даты от ваших инициализаторов.

0

Если вам нужно настроить свойство, то я пошел бы на пути vadian в. Но ваш код установки требует некоторой процедуры, например, подготовки сложной структуры или подготовки кэшей изображений, тогда мне нравится идти на ленивый трюк с закрытием. Это закрытие установки выполняется только один раз, как и любые другие ленивые свойства var инициализируются один раз. Поэтому здесь вы можете написать довольно сложный процедурный код. Не забудьте добавить private, тогда ваши подклассы не будут мешать вашему бизнесу.

class MyViewController: NSViewController { 

    init() { 
     super.init(nibName: nil, bundle: nil)! 
     self.setup() 
    } 

    override init?(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     self.setup() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.setup() 
    } 

    override func encodeWithCoder(aCoder: NSCoder) { 
     super.encodeWithCoder(aCoder) 
    } 

    lazy private var setup:()->() = { 
     // do some complex procedure here!! 
     return {} 
    }() 
} 
+0

Спасибо за ваше предложение. Меня особенно интересует, как присваивать значения константам, которые должны выполняться в методе init. –

Смежные вопросы