ぜのぜ

写真以外をそのままのっけるブログ

52日目

日記

最近オリンピックを見てるんだけど,フェンシングとセーリングがお気に入り.好きな競技をストリーミングで見られるなんていい時代ですね.

プログラミングは勢いで始めてもコスト0でやめられていいな.自転車だと進むも地獄退くも地獄になりがち.去年の夏イズイチしたときは走りながらずっと文句言ってた.

今日書いたコード

その2 github.com

初めて知ったこと

なし

51日目

日記

今日はなにもないけど酒を飲む.今日は冷凍ご飯が切れてて炊くのもめんどくさかったから夕飯調達がてら酒を買ってきた.

今日書いたコード

Apple PodcastsのBrowserタブを真似する(1)ということで業務でコレクションビューをめちゃくちゃ使うので力試しがてらApple PodcastsのBrowserタブを真似しようと思った.

github.com

初めて知ったこと

なし

50日目 (!!

日記

オリンピックのロードレースを見てテンション上がったので今日から夜練を始めてみた.俺は脳死でコツコツやってればある程度成長できるやろという感じで生きてきたので今回もそんな感じで成長したい.が,洗濯と風呂が結構なコストである.

そういえばこの習慣も今日で50日目らしい.いくつかは知らなかったことを知れたのでやって悪くはなかったと思う.

今日書いたコード

class Food: CustomStringConvertible {
    var name: String
    var description: String {
        "name: \(name)"
    }

    init(name: String) {
        self.name = name
    }
    convenience init() {
        self.init(name: "[Unnamed]")
    }
}

print(Food(name: "Banana"))
print(Food())

class RecipeIngredient: Food {
    var quantity: Int
    override var description: String {
        super.description + ", quantity: \(quantity)"
    }

    init(name: String, quantity: Int) {
        self.quantity = quantity
        super.init(name: name)
    }
    override convenience init(name: String) {
        self.init(name: name, quantity: 1)
    }
}

// サブクラス独自のDesignated Initializerを実装しているので自動的には継承されないが,
// スーパークラスのDesignated Initializerを全て実装しているのでConvenience Initializerが継承される
print(RecipeIngredient(name: "Egg", quantity: 12))
print(RecipeIngredient(name: "Apple"))
print(RecipeIngredient())

class ShoppingListItem: RecipeIngredient {
    var purchased = false
    override var description: String {
        super.description + ", purchased: \(purchased)"
    }
}

// サブクラス独自のDesignated Initializerを実装していないので,
// スーパークラスのDesignated InitializerとConvenience Initializerが全て継承される
print(ShoppingListItem(name: "Milk", quantity: 1))
print(ShoppingListItem(name: "Onion"))
print(ShoppingListItem())
name: [Unnamed]
name: Banana
name: Egg, quantity: 12
name: Apple, quantity: 1
name: [Unnamed], quantity: 1
name: Milk, quantity: 1, purchased: false
name: Onion, quantity: 1, purchased: false
name: [Unnamed], quantity: 1, purchased: false

初めて知ったこと

なし.今回は今までの説明の確認回だった.

そういえば技術書典で買ったSwiftイニシャライザ大全(うろ覚え)という本が積んであるのでこの章を読み終わったらその本も読もうと思う.

49日目 Automatic Initializer Inheritance

日記

窓開ければ結構涼しいと思ったがやっぱ無理.これこそ在宅勤務手当の使い所.

初めて知ったこと

Automatic Initializer Inheritance

スーパークラスのイニシャライザの継承に関するルール

  1. サブクラスで一つもDesignated Initializerを定義しなければ,自動的にスーパークラスの全てのDesignated Initializerを継承する
  2. ルール1による継承もしくは,クラス定義の一部としての独自実装によってスーパークラスの全てのDesignated Initializerを実装していれば,自動的にスーパークラスの全てのConvenience Initializerを継承する

Rule 1

If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

Rule 2

If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.

スーパークラスのDesignated Initializerが継承されないパターン

ルール2によってConvenience Initializerも継承されない

class Sup {
    let str: String

    init(_ str: String) {
        self.str = str
    }

    convenience init(isHoge: Bool) {
        self.init(isHoge ? "hoge" : "")
    }
}

class Sub: Sup {
    init() {
        super.init("str")
    }
}

// Argument passed to call that takes no arguments
// print(Sub("str").str)
// Argument passed to call that takes no arguments
// print(Sub(isHoge: true).str)

スーパークラスのDesignated Initializerを継承することによってConvenience Initializerも継承するパターン

class Sup {
    let str: String

    init(_ str: String) {
        self.str = str
    }

    convenience init(isHoge: Bool) {
        self.init(isHoge ? "hoge" : "")
    }
}

class Sub: Sup {}

print(Sub("str").str) // str
print(Sub(isHoge: true).str) // hoge

独自実装によってConvenience Initializerも継承するパターン

class Sup {
    let str: String

    init(_ str: String) {
        self.str = str
    }

    convenience init(isHoge: Bool) {
        self.init(isHoge ? "hoge" : "")
    }
}

class Sub: Sup {
    override init(_ str: String) {
        super.init(str.uppercased())
    }
}

print(Sub("str").str) // str
print(Sub(isHoge: true).str) // hoge

スーパークラスのDesignated Initializerを全て実装せずにConvenience Initializerを継承することができないのは,Convenience Initializerは必ずそのクラスのDesignated Initializerを呼ばないといけないという決まりがあるからだと思う.(スーパークラスのDesignated Initializerを呼ぶConvenience Initializerを定義できない.

A convenience initializer must call another initializer from the same class. Initializer Delegation for Class Types

48日目 しゅうまつ

日記

一瞬で4連休が終わってしまった.しかもこの週末は例のお気に入りの生主の放送がなかったのでこの先生きのこれる気がしない.週末じゃなくて終末だよ

今日書いたコード

class Sup {
    let str: String

    init() {
        print("Sup init")
        str = "str"
    }
}

class Sub: Sup {
    init(str: String) {
        print("Sub init", str)
    }

    convenience override init() {
        print("Sub convenience init")
        self.init(str: "some")
    }
}

Sub().str
print("---")
Sub(str: "some")
// Sub convenience init
// Sub init some
// Sup init
// ---
// Sub init some
// Sup init

初めて知ったこと

スーパークラスのイニシャライザが,引数を取らないDesignated Initializer1つだけのとき,サブクラスのイニシャライザの処理が終わったあとにそのイニシャライザが呼ばれる.

Chris_Lattner May '16

Two reasons:

1) No one wants to call super.init() when deriving from NSObject.

2) More generally, if there is exactly one DI in your superclass, and if it takes zero arguments, it is usually not interesting to have to call it, it is just boilerplate.

If you think that this is the wrong policy, please bring it up on swift-evolution. Note that this has been the behavior since Swift 1, and I haven’t heard any other serious complaints about it.

-Chris

https://forums.swift.org/t/super-init-called-automatically/2643/7

47日目

日記

休日が実質残り1日しかないので泣きそう.そういえば右上のはてなのロゴが変わってる.

今日書いたコード

struct Size {
    var width = 0.0, height = 0.0
}
struct Point {
    var x = 0.0, y = 0.0
}

struct Rect {
    var origin = Point()
    var size = Size()

    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)

        origin = Point(x: originX, y: originY)
        self.size = size
    }
}

struct AnotherRect {
    var origin = Point()
    var size = Size()
}

extension AnotherRect {
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}

print(Rect().origin) // Missing arguments for parameters 'center', 'size' in call
print(AnotherRect().origin)

初めて知ったこと

定義の中にカスタムイニシャライザを書くとデフォルトイニシャライザは提供されなくなるが,extensionの中で書くと提供される.

46日目

日記

ということで思い出したので今日も書いた

今日書いたコード

import Foundation
class ShoppingListItem {
    let id = UUID()
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()
print(item.id) // B011DA4F-F931-4BB2-A05E-CD0DB7C50FEA

初めて知ったこと

classの全てのプロパティがデフォルト値を持っていればdefault initializerが使える.