はじめに
メモリリークの勉強中,自分のアプリでミスが見つかったので備忘録.
例
macOSアプリだとWindowController
を管理しないといけないのですが,NSWindow
周りのイベントを扱うためにNSWindowDelegate
を使います.何も考えずに必要なところで処理を行うためにWindowController
とViewController
の両方にDelegateを継承してウィンドウのイベントを取得していたのですが,そのせいでウィンドウを閉じてもdeinit
されない現象が起きていたことに気づきました.
WindowControllerサイド
import Cocoa
class WC: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
self.window!.delegate = self
}
func windowWillClose(_ notification: Notification) {
self.contentViewController = nil
}
}
ViewControllerサイド
import Cocoa
class VC: NSViewController, NSWindowDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear() {
self.view.window!.delegate = self
}
func windowDidResize(_ notification: Notification) {
// リサイズ時の処理
}
deinit {
Swift.print("deinit したよ") // <- 呼ばれない
}
}
所感
職業エンジニアの方なら常識的なことかもしれませんが,独学の学生エンジニアだと動けばいい(まずは動くところまで実装するのでやっと)という感じでえいやっと実装しているのでなかなかこういう大切なことが学べていません...
C言語から入った人なので一応メモリに対する意識はごくわずかでもあるのが救いですね.