Skip to content

Instantly share code, notes, and snippets.

@creaaa
Last active November 4, 2018 07:01
Show Gist options
  • Save creaaa/1001bdf293cd8444a42f85ca66d3761b to your computer and use it in GitHub Desktop.
Save creaaa/1001bdf293cd8444a42f85ca66d3761b to your computer and use it in GitHub Desktop.
staticなプロパティの生存期間
import UIKit
class StaticClass {
static var pokemon = Pokemon(name: "Pikachu")
deinit {
print("static class died")
}
}
class Pokemon {
let name: String
init(name: String) {
print("\(name) was born")
self.name = name
}
deinit {
print("\(name) died")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let pikachu1 = StaticClass.pokemon
let pikachu2 = StaticClass.pokemon
print(pikachu1 === pikachu2) // true
StaticClass.pokemon = Pokemon(name: "リザードン") // Pikachu died
}
}
// 1. タイププロパティの値の式は、アクセスされた時点で初めて評価される(lazyと似ている)
// 2. タイププロパティの値を格納した変数が死んでも、タイププロパティの値(Pickachuインスタンス)は生存し続ける。
// (∵ カウント0かと思いきや、
// プロパティ StaticClass.pokemon には参照され続けており、ARCカウント+1になっているので)
// このタイププロパティ StaticClass.pokemon 自体をアプリから亡き者にするのは超AAA級、相当難しいだろう...
// ただ、StacicClass.pokemon に別のポケモン(リザードン)を代入すると、
// Pikachuインスタンスのdeinitが呼ばれる("Pikachu died と表示される)
// ∵ Pokeomon(Pikachu)を指している変数はいまやなくなったから
@creaaa
Copy link
Author

creaaa commented Nov 4, 2018

結論

タイププロパティ変数に代入されているインスタンスを殺す方法は、var であれば、再代入することで参照カウントを0にすること。
そのタイププロパティがlet だったり、privateだったら99.999%無理だろう。

また、タイププロパティ自体を殺すのは相当難しいだろう。ほぼ不可能と言って良い。
タイププロパティとは「型」に紐づくもの。
インスタンスには生死が問題になるが、タイプ(型)はインスタンスを生み出すための設計図であり、
インスタンスとして生まれることもなければ死ぬこともなく、アプリ起動中、「ただ、そこにあるもの」。
そんな「タイプ」のプロパティ(プロパティに代入されている値ではない)を、果たしてどうやって殺せというのか。

@creaaa
Copy link
Author

creaaa commented Nov 4, 2018

プロパティがstaticになった時点で、(private出ない限り)どこからでもアクセスされてしまう。
アクセスを、"ある機能を司る画面内からのみに制限する"のは、相当難しそうだな...
本気なら、staticではなく、別の手段を考えたほうがよさそう

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment