-
Notifications
You must be signed in to change notification settings - Fork 0
Version 4 の最新情報
ついに Version 4.0.0 リリースしました!! Wiki の更新は随時行ってまいります. また, SKNodeBuilder は Documentation catalog に簡単なガイドを載せておりますので, そちらも是非ご参考に.
現在開発中の Builder
の構造を図示しました.
![Builder 001](https://user-images.githubusercontent.com/87851278/200272954-b677359a-59f5-4181-b4d3-984a9df6d766.png)
- Builder は Generator と Processor を保持します.
- Processor は入れ子構造になっており, それぞれが Modifier を保持します.
- 図では
Link
となっていますが, これも Processor の一種です.
-
Generator
がSKNode
のインスタンスを生成します. - 生成されたインスタンスは
Processor
の入れ子の最奥部まで移動します. - インスタンスが
Processor
の最奥から外へ向かって移動し, その際にModifier
がインスタンスを編集します.
モディファイアを追加すると, ビルダーの型が変化します.
Modifier changes the type of the builder.
![linked-modifier-sample-code](https://user-images.githubusercontent.com/87851278/200579891-ba11a51c-707f-4f6b-82b5-ae6cbad4dcab.png)
何が良くなった?
Version 3 との大きな違いは, ビルダーがノードのインスタンスを保持しないことです. Version 4 では, 上の写真でコメントアウトされている, node()
メソッドを実行して, 初めてノードのインスタンスが作られます. ビルダーがノードを保持しないことで得られるメリットは以下の通りです.
- ビルダーオブジェクトが value semantics を持つことができる(ただし, modifier の実装による).
- ビルダーオブジェクトが参照を持たないため, メモリーリークをすることがなくなる(ただし, modifier の実装による).
ビルダーの value semantics を破壊する modifier とは?
先ほどの説明ではこんなことが書いてありました.
(ただし, modifier の実装による)
いったいどんな modifier を作ったら value semantics を破壊するのでしょう? 結論から言うと, 参照型のインスタンスを使用する modifier が, モディファイアをセットした Builder 全体の value semantics を破壊します.
例えば, あなたがカスタムモディファイアとして以下のような参照を持つモディファイアを作ったとします.
struct YourMod<T: SKNode>: Modifier {
var anotherNode: SKNode // ここが参照!
func mod(node: T) {
node.addChild(self.node)
}
}
このモディファイアをビルダーにセットすると, そのビルダーは value semantics が破壊され, かつ循環参照を作ることができる(この時点では循環参照になりません)ようになるため, メモリリークの危険もどこかで現れるかもしれません.
- tips: この場合, せめて
weak var
やunowned let
を使うといいかもしれません. 循環参照だけでも回避できますので.
以下は悪影響の例です.
// 参照を持つモディファイアが Builder の value semantics を破壊する様子.
// 変数 builder_0 が 変数 builder_1 に影響を及ぼしている.
let node = SKNode()
let modifier = YourMod<SKNode>(anotherNode: node)
let builder_0 = Builder()
.modifier(modifier)
let builder_1 = Builder()
.modifier(modifier)
let node_0 = builder_0.node()
let node_1 = builder_1.node() // error! 同一のノードを別々のノードに接続してしまった!
Modifier
プロトコルを使用してモディファイアを作成できます.
struct YourMod: Modifier {
func mod(node: SKLabelNode) {
node.text = "My modifier!!"
node.fontColor = .red
}
}
let builder = Builder<SKLabelNode>()
.modifier(YourMod())
定義済みのノードを編集する意図でビルダーを使えるようになりました.
ついにノードの初期化を実現しました!
ノードの初期化を実現したオブジェクトは, Generator
と名付けられました.
Generator は Processor とともに Builder
に装備され, これにより Builder はさまざまなイニシャライザでノードを初期化することができるようになりました.
Generator の生成は, Generators<Node>.make()
メソッドで作成できます.
しかし新たな欠点が生まれました。それは、生成に必要なコードが長くなってしまったことです。version 5 に向け、現在のメモリ管理システムをなるべく維持しながら、コード量を短くできる方法を模索しています。