★ 以下はvalue
が初期化されていないのでエラー
//=> Class 'InitClass' has no initializers
class InitClass {
let value: Int
}
★ Default Initializer
イニシャライザでプロパティに値をセットする必要が無い場合に、Designated Initializerが実装されていない場合は以下のようにDefault Initializerが暗黙的に追加されます。
// 変数の初期化時に初期値を代入する
class InitClass {
let value: Int = 0
}
// 変数の初期値がOptionalでnilで初期化される
class InitClass {
let value: Int?
}
★ 指定イニシャライザ : designated initializer インスタンスの初期化がすべて完了できるイニシャライザ
class InitClass {
var value: Int
// Designated initializer
init() {
value = 0
}
}
var initClass = InitClass()
★ 簡易イニシャライザ : convenience initializer
イニシャライザの中で別のイニシャライザを呼ぶことができる
class InitClass {
var value: Int = 0
// Designated initializer
init() {
}
// Convenience initializer
convenience init(value: Int) {
self.init()
self.value = value
}
}
// --- Usage ---
let designated = InitClass()
designated.value
//=> 0
let convenience = InitClass(value: 1)
convenience.value
//=> 1
★ 必須イニシャライザ : required initializer
継承先のサブクラスで、初期化処理をする時は必ず実装しなければならないイニシャライザ
class InitClass {
var value: Int
// Designated initializer
init() {
value = 0
}
// Required initializer
required init(value: Int) {
self.value = value
}
}
class subInit: InitClass {
// Override initializer
override init() {
super.init()
value = 1
}
// Required initializer
required init(value: Int) {
fatalError("init(value:) has not been implemented")
}
}
class InitClass {
var value: Int
// Designated initializer
init() {
value = 0
}
// Required initializer
required init(value: Int) {
self.value = value
}
}
class SubInit: InitClass {
// 初期化処理しない場合はRequired initializerも実装する必要が無い
}
// --- Usage ---
let subInit = SubInit()
subInit.value
//=> 0
let requiredInit = SubInit(value: 1)
requiredInit.value
//=> 1
★ 失敗のあるイニシャライザ : failable initializer
初期化が失敗した場合にnilを返すイニシャライザ
class InitClass {
var value: Int = 0
// Failable initializer
init?(value: String) {
guard let value = Int(value) else {
return nil
}
self.value = value
}
}
var initclass = InitClass(value: "a")
//=> nil
★ Memberwise Initializer (Structのみ)
Structureに対してイニシャライザが実装されていない時に
イニシャライザで値の代入が必要なプロパティがある場合にそれらを引数にとったイニシャライザが暗黙的に追加されます
これをMemberwise Initializerといいます。
struct Sample {
let name: String = "Guest"
let number: Int
}
let sample = Sample(number: 1)
★ Sub Classから呼び出せるのはSuper ClassのDesignated initializerのみ
class InitClass {
var value: Int
// Designated initializer
init() {
value = 0
}
// Convenience initializer
convenience init(value: Int) {
self.init()
self.value = value
}
}
class subInit: InitClass {
// Override initializer
override init() {
super.init(value: 5) // Error
// Must call a designated initializer of the superclass 'initClass'
}
}
★ UIViewController
import UIKit
class CustomViewController: UIViewController {
// Storyboardでの生成
// ① required init
// コードでの生成
// ① override init
// ② convenience init
// コードでCustom Initializerでの生成
// ① override init
// ② Custom convenience init
// Storyboardからの生成時に呼ばれる(Designated initializer)
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
print("required init")
setup()
}
// コードでの生成時に呼ばれる① (Designated initializer)
override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
super.init(nibName: nil, bundle: nil)
print("override init")
setup()
}
// コードでの生成時に呼ばれる②(Convenience initializer)
convenience init() {
self.init(nibName: nil, bundle: nil)
print("convenience init")
}
// Custom Initializer(Convenience initializer)
convenience init(color: UIColor) {
self.init(nibName: nil, bundle: nil)
self.view.backgroundColor = color
print("Custom convenience init")
}
func setup() {
// init処理
print("SetUp")
}
deinit {
// 終了処理
}
}
★ UIView
class CustomView: UIView {
// Designated initializer
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
// Designated initializer
override init(frame: CGRect) {
super.init(frame: frame)
}
// Convenience initializer
convenience init(bg_Color: UIColor) {
self.init()
self.backgroundColor = bg_Color
}
}
★ UIViewのサブクラスを特定のInitializerでしか初期化をさせたくない場合
class CustomView: UIView {
init(backColor: UIColor) {
super.init(frame: CGRectZero)
self.backgroundColor = backColor
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// init(backColor: UIColor)のみでしか初期化はできない
let vi = CustomView(backColor: UIColor.yellowColor())
vi.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
view.addSubview(vi)
★ 初期化アレンジ
class SuperClass {
init(sender: String, recipient: String) {
}
}
class SubClass: SuperClass {
var content: String = ""
init(content: String, sender: String, recipient: String) {
self.content = content
// スーパークラスの初期化を呼び出し
super.init(sender: sender, recipient: recipient)
}
convenience init() {
// 自身の初期化を呼び出し
self.init(content: "")
}
convenience init(content: String) {
// 自身の初期化を呼び出し
self.init(content: content, sender: "Myself")
}
convenience init(content: String, sender: String) {
// 自身の初期化を呼び出し
self.init(content: content, sender: sender, recipient: sender)
}
}
★ class
class InitClass {
var value: Int
init() {
value = 0
}
}
let obj = InitClass()
★ struct
struct InitStruct {
var value: Int
init() {
value = 0
}
}
let st = InitStruct()
★ enum
enum Size {
case Small
case Medium
case Large
// 引数なしコンストラクタ
init() {
self = .Small
}
// 引数ありコンストラクタ
init(size: Size) {
self = size
}
}
var size1 = Size()
//=> Small
var size2 = Size(size: .Medium)
//=> Medium
★ 既存のinitializerを使用して拡張する
import UIKit
class ViewController: UIViewController {
var fontArray = ["Zapfino","DBLCDTempBlack","MarkerFelt-Thin"]
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label.text = "text"
label.font = UIFont(name: fontArray[0])
}
}
extension UIFont {
convenience init?(name: String) {
self.init(name: name, size: 7)
}
}
★ 初期化後にしかアクセスできなな変数
class B {
var v1: Int!
// こっちのが良い
lazy var v2: Int = {
fatalError("`\(#function)` is not initialized")
}()
}
let b = B()
// fatal error: unexpectedly found nil while unwrapping an Optional value
//b.v1.description
// nil 入っちゃう
b.v1 = nil
// fatal error: `v2` is not initialized
//b.v2.description
// nil は入り得ない
//b.v2 = nil