View Controllerの寿命の終わりに、つまりNSNotificationCenter
通知を削除するために、クリーンアップを実行したいと思います。 dealloc
を実装すると、Swiftコンパイラエラーが発生します。
Cannot override 'dealloc' which has been marked unavailable
Swiftでのオブジェクトの寿命の終わりにいくつかのクリーンアップを実行する好ましい方法は何ですか?
deinit {
// perform the deinitialization
}
初期化解除子は、クラスインスタンスの割り当てが解除される直前に呼び出されます。 initializersがinitキーワードで記述される方法と同様に、deinitキーワードでdeinitializersを記述します。非初期化子は、クラス型でのみ使用可能です。
通常、インスタンスの割り当てが解除されたときに手動でクリーンアップを実行する必要はありません。ただし、独自のリソースを使用している場合は、追加のクリーンアップを自分で実行する必要がある場合があります。たとえば、ファイルを開いてデータを書き込むカスタムクラスを作成する場合、クラスインスタンスの割り当てを解除する前にファイルを閉じる必要があります。
deinit {
// perform the deinitialization
}
Swift "dealloc"の正解です。
ただし、NSNotificationCenterをクリーンアップする必要がなくなったことをiOS 9で新たに指摘することをお勧めします。
NSNotificationCenter
OS X 10.11およびiOS 9.0では、NSNotificationCenterおよびNSDistributedNotificationCenterは、割り当て解除された可能性のある登録済みオブザーバーに通知を送信しなくなりました。オブザーバーをゼロ化弱参照として保存できる場合、基礎となるストレージはオブザーバーをゼロ化弱参照として保存します。あるいは、オブジェクトを弱く保存できない場合(つまり、ランタイムを妨げるカスタムの保持/解放メカニズムがあります)オブジェクトを弱く格納できることから)、オブジェクトを非ゼロのゼロ化参照として格納します。これは、オブザーバが割り当て解除メソッドで登録解除する必要がないことを意味します。そのオブザーバーにルーティングされる次の通知は、ゼロ化された参照を検出し、オブザーバーを自動的に登録解除します。オブジェクトの弱参照が可能な場合、割り当て解除中にオブザーバーに通知が送信されなくなります。参照オブザーバが弱くゼロ化されていない場合、dealloc中に通知を受信する以前の動作は引き続き存在します。 -[NSNotificationCenter addObserverForName:object:queue:usingBlock]メソッドを介したブロックベースのオブザーバーは、システムがこれらのオブザーバーへの強力な参照を保持しているため、使用しなくなった場合は登録解除する必要があります。観測者(弱参照またはゼロ参照)の早期削除は引き続きサポートされます。オブザーバはオブジェクトではない可能性があるため、CFNotificationCenterAddObserverはこの動作に準拠していません。
ただし、強力な参照に関する以下の点に注意してください。とにかく、クリーンアップについて心配する必要があるかもしれません...?
Swiftは、不要になったインスタンスを自動的に割り当て解除して、リソースを解放します。 Swiftは、自動参照カウントで説明されているように、自動参照カウント(ARC)を介してインスタンスのメモリ管理を処理します。通常、インスタンスの割り当てが解除されたときに手動でクリーンアップを実行する必要はありません。ただし、独自のリソースを使用している場合は、追加のクリーンアップを自分で実行する必要がある場合があります。たとえば、ファイルを開いてデータを書き込むカスタムクラスを作成する場合、クラスインスタンスの割り当てを解除する前にファイルを閉じる必要があります。
クラス定義には、クラスごとに最大1つの初期化解除子を含めることができます。デイニシャライザーはパラメーターを使用せず、括弧なしで記述されます。
deinit
{
// perform the deinitialization
}
割り当てを解除する前にオブザーバーを削除する必要があります。そうしないと、クラッシュが発生します。それを使用して行うことができます
deinit {
// perform the deinitialization
print("deinit")
removeObserver(self, forKeyPath: kSelectedViewControllerKey, context: nil)
removeObserver(self, forKeyPath: kSelectedIndexKey, context: nil)
}