今知っていること

  • クラス
    • クラスは[[SomeClass alloc] init] とかSomeClass.init(with: value) みたいなイニシャライザでインスタンスを作る。
    • メソッドにはクラスメソッドとインスタンスメソッドがあり、後者はオブジェクトに備わっている
    • 昔の現場ではmybatis使ってるサーバ側に合わせて単なるマッパーでしかないモデルクラスを作っていて案の定コントローラが肥大し、途中でモデル側に最低限のメソッドを積むようにしていた。
  • 構造体
    • 構造体は値型、クラスは参照型
    • SwiftについてはCoWのため別のところに代入しても何か変更を加えなければメモリを消費しないらしい
  • 参照型はfor文とかでarrayの中身を取り出して処理していると気づいたら変わっているので好き
    • 知らないところで変わっていると死ぬ
    • objcはmutable型があったため区別は一応ついたしswiftは基本immutableで進められるから安心感がある
  • クロージャは仕事じゃないと絶対に(面倒で)使わなかっただろうけど今はこれなしで処理作れない(arrayの処理をfor文でなくブロック式でやるように指導してくれた先輩には感謝しかない)
    • [weak self] は正直なんとかしたい感はある
    • 油断するとネストが深くなり「これがコールバック地獄か・・・」という気持ちになれたので早くaysnc await欲しい
  • 関数プログラミングはよくわからないけどswiftでmap, reduce, etc. ができたおかげでtotalXXXな変数をmutableで宣言→すぐ下でfor文回すみたいなコードを作らなくてよくなってQOLが上がった。
  • main関数は特別
    • objcでも実はmain関数から始まっていた(クラッシュしたときに見ることが割とよくあった)。Swiftで最初から作ったアプリだと見ないなあ
  • テストは大事
    • 最初のところだと単機能の実装に対してexcelで100超えの項目書を作っていたがもうやりたくない
    • XCTest最高!ModelとViewModelなら境界値とシンプルなユースケースは網羅できて幸せ
    • 現実的なUITestってあるのかなあ
  • nil(null)の取り扱いは面倒臭い
    • Optionalは本当に助かってる。nilが入る可能性のない箇所と仕方なく入る箇所が切り分けられるのでコーディングに不安がないし、Javaぬるぽ踏んだので勘弁して欲しい
  • ポインタはわからない
    • objcでは雰囲気で使ったけどよく考えたらNSInteger系は値型だったからアスタリスクつけなくても良かったのかな?付けなくてもいいのにNSInteger *intValue にしたせいで不具合になっていた以前の現場を思い出した
  • メモリ管理よくわからない
    • ARC時代しか知りません(autorelease poolは稀に使った(もう覚えていない))
    • 稀にメモリリークすることがあり、古参の先輩がMRC時代の手動管理の話をしてくれたことがあった
    • objc, Swift はC言語系で参照カウント方式とかJava系はGCがあるという概念の話は聞いている

Swiftで旧漢字を判定したかった

できなかった

  • 方針その1: shift-jisに変換できるかどうかで判別する

参考: www.softel.co.jp

extension String {
    func containsOldKanji() -> Bool {
        return !self.canBeConverted(to: .shiftJIS)
    }
}

let str = "高"
str.containsOldKanji() // true

let str2 = "髙"
str2.containsOldKanji() // なぜかtrue

後々の試行錯誤中にshift-jis変換がうまくいっていることが判明し、IBM拡張なるものを知る
f:id:slowlylearner:20180104033139p:plain
文字コード表 シフトJIS(Shift_JIS)

  • shift-jis変換は成功しているので、IBM拡張の範囲(纊~黑まで)の漢字が含まれているかどうかを判定する

結果から言うとだめ

extension String {
    func containsOldKanji() -> Bool {
        //        return !self.canBeConverted(to: .shiftJIS)
        return containsIBMExtension()
    }
    
    
    func containsIBMExtension() -> Bool {
        guard let data = self.data(using: .shiftJIS),
            let shiftJISStr = String(data: data, encoding: .shiftJIS)
            else {
                return false
        }
        
        // http://charset.7jp.net/sjis.html のIBM拡張(?)で漢字相当の範囲を引っ掛ける
        let regEx = ".*[\u{ed40}-\u{eeec}]+.*"
        let test = NSPredicate(format: "SELF MATCHES %@", regEx)
        return test.evaluate(with:shiftJISStr)

上の後でパターンの方もshiftjisにしないとだめかなーとか漢字をダイレクトにパターンに入れてしまえばいいのではないかと思ったがダメだった。

extension String {
    func containsOldKanji() -> Bool {
        //        return !self.canBeConverted(to: .shiftJIS)
        return containsIBMExtension()
    }
    
    
    func containsIBMExtension() -> Bool {
        guard let data = self.data(using: .shiftJIS),
            let shiftJISStr = String(data: data, encoding: .shiftJIS)
            else {
                return false
        }
        
        // http://charset.7jp.net/sjis.html のIBM拡張(?)で漢字相当の範囲を引っ掛ける
        let regEx = ".*[纊-黑]+.*"
        guard let dataRegEx = regEx.data(using: .shiftJIS),
            let shiftJISRegEx = String(data: dataRegEx, encoding: .shiftJIS)
            else {
                return false
        }
        
        let test = NSPredicate(format: "SELF MATCHES %@", shiftJISRegEx)
        return test.evaluate(with:shiftJISStr)

最後の方は両方ともcontainsOldKanjiがtrueを返していたので「纊-黑」の範囲がshift-jisではなくutf-16とかunicodeとかで解釈されている可能性があり、そもそも何がどうなるとswiftの時代にshift-JISで正規表現を書くのだろうかという気持ちになった。

20181231

睡眠

4:49入眠 10:55起床
6:03時間睡眠

itっぽいこと

Type erasureでプロトコルのequatableを逃がすことができた

その他
  • 今月は36程度のZが発生していた。20くらいにしたい
  • 1年半経験の転でもやっていけることが判明した奇跡
  • elinをさわれた奇跡
  • 来年はもう少しましな生活が送れますように

20171130

睡眠

4:00入眠 11:00起床
7時間睡眠 睡眠負債は5.0h

itっぽいこと

型を消去しないとEquatableが実装できないという悲しい現実に打ちひしがれた

その他

コルム美味しい!一番好きなチャンピオンです!