>100 Views
July 12, 15
スライド概要
#yidev 横浜 iPhone 開発者勉強会の第18回で話す予定だったスライドをアップしました。構造体に主眼をおいてみてみよう、そんなお話です。
内容的には、以前の第60回 Cocoa 勉強会関西で話したスライドを端的にまとめたスライドです。少し前のスライドになりますけど、ざっと見た感じ、今の Swift 2 でも参考できそうな様子でした。
※ Docswell での公開に移行する直前の Slideshare での閲覧数は 3,820 でした。
正統派趣味人プログラマー。プログラミングとは幼馴染です。
Swift カジュアルプログラミング 《余談》構造体の時代 EZ-NET 熊谷友宏 http://ez-net.jp/ 2015.03.07 @ yidev 第18回勉強会
熊谷友宏 http://ez-net.jp/ @es̲kumagai Xcode 5 徹底解説 IP Phone 音でダイヤル 音で再配達ゴッド いつもの電卓 for iPhone いつもの電卓 for iPad 音で再配達
2014 Swift 構造体元年
これまで & これから
これまで Objective-C クラス Primitive 構造体
これから Swift 型 構造体 クラス
これまでの定義 Objective-C // 構造体の定義 typedef struct { int v; } MyStruct; // クラスの定義 @interface MyClass : NSObject @property (readwrite) int v; @end
これからの定義 Swift // 構造体の定義 struct MyStruct { var v:Int32 } // クラスの定義 class MyClass { var v:Int32 }
これまで&これから これまでの使い方 Objective-C MyStruct s = { 0 }; MyClass* c = [[MyClass alloc] init]; これからの使い方 Swift let s = MyStruct() let c = MyClass()
これまで&これから Objective-C Swift ▶ 構造体は脇役 ▶ 構造体が主役
原則的な話
構造体 これまで ▶ 複合データ型 これから ▶ 値や状態を表現する型
値とは、定まるもの ▶ 評価したい式で使うもの ▶ 何かの式を評価したもの たとえば a = f(x,y,z)
状態とは、変化するもの ▶ 時間軸で変化する値 ▶ 今の “有り様” を表現するもの たとえば location: (x,y) capacity: ㎖
値と状態 それぞれ別の変数で表現 値 ▶ 不変値変数 let 状態 ▶ 可変値変数 var
これから 変数自体が意味を持つ時代 // 平面を動く物体の座標 var location:(x,y) // 平面座標の値 let location:(x,y)
これから 構造体の性質が格納先で変化 不変値変数 let ▶ Immutable 扱い 可変値変数 var ▶ Mutable 扱い let s = MyStruct() s.value = 10 var s = MyStruct() s.value = 10
これから 値や状態で使う型は 原則、構造体で定義 ▶ String ▶ Array ▶ Int
クラスは?
クラス これまで ▶ オブジェクト型 これから ▶ 状態を制御する型
クラス 状態を制御 ▶ 制御対象の状態を持つ ▶ 状態を制御する機能の集合体 状態は更新可能 let s = MyClass() var s = MyClass() s.value = 10 s.value = 10
コンセプトの違い 構造体 ▶ 値や状態を表現する型 クラス ▶ 状態を制御する型
コンセプトによる違い 同じ書き方で違う仕上がり 構造体 クラス let s = MyStruct() let c = MyClass() 値 実体 制御 状態 (var なら状態)
コンセプトによる違い let で保護されるところ 構造体 クラス let s = MyStruct() let c = MyClass() 値 実体 値の全体 実体のみ 制御 状態
運用
値と状態 おさらい 値 ▶ 不変値変数 let 状態 ▶ 可変値変数 var
値と状態は 相互に乗り入れ可能
カギは 変数のコピー
コピー 状態 値 固定のもの 連動を断ち切る 変化するもの コピー 連動を断ち切る let value = 0 var state = value ここで断ち切る 状態 変化するもの
構造体は コピーが原則
ちなみに
クラスのコピーは実体だけ 実体 実体 制御する状態は共有 状態 let instance1 = 0 let instance2 = instance1 実体を複製、状態は共有
最適化
コピーの指示 これまで Objective-C // 明示コピー NSString* str2 = [str1 copy]; これから Swift // 原則コピー let str2 = str1
コピーの指示 これまで Objective-C ここでコピー!と言っている // 明示コピー NSString* str2 = [str1 copy]; これから Swift ここでコピー!とは言ってない // 原則コピー let str2 = str1
原則コピーで タイミングを言語に委ねられる
原則コピーは 最適化がしやすい
もうひとつの最適化
構造体の基本原則 ▶ 内容はコピー 別の変数へ代入時は内容をコピー ▶ 原則コピー 原則に従えばタイミングは問わない
Array の最適化 ▶ 内容はコピー 別の変数へ代入時は内容をコピー ▶ 原則コピー ただし必要な時までコピーされない
配列コピーのタイミング コピー 配列 配列 バッファーは共有 Buffer
配列コピーのタイミング 書き込み! 配列 配列 × Buffer Buffer 遅延コピー
Array は最適化設計 原則に沿って遅延コピー
ところで 疑問
マルチスレッドでの挙動は…? Thread 1 配列 Thread 2 コピーして渡したつもり Buffer × 配列 Buffer 遅延コピー 書き込み!
未確認 なんとなく危なそう
明示コピーの方法は? Swift Beta 2 時代 ▶ unshare() 今は使えない Swift 1.2 で実現するとしたら…? ▶ map { $0 } スマートではない
おしまい これまでとこれから ▶ これからは構造体が主役 ▶ 値と状態を扱うオブジェクト 原則 ▶ 内容は原則コピー ▶ 原則コピーで最適化を図る マルチスレッド周りは? ▶ 未確認 !