メソッドをクロージャを受け取る関数に渡すときに、someFunc(){[unowned self] in self.someMethod()} `のいずれかを使用できます。メソッドを関数に渡すときに強い参照を避ける
最初の文字は短い文字ですが、参考になります。この強力な参照を避けてどのように使用できますか?ここで
が漏れて1と良いものの両方でのデモです: https://swiftlang.ng.bluemix.net/#/repl/581ccd3a0bdc661a6c566347
import Foundation
private var instanceCounter = 0
class Leak : NSObject {
override init() {
super.init()
instanceCounter += 1
}
deinit {
instanceCounter -= 1
}
}
class OnFunctionLeak : Leak {
override init() {
super.init()
_ = NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "OnFunctionLeak"),
object: nil,
queue: nil,
usingBlock: doNothing)
}
func doNothing(_ notif: Notification) { }
deinit {
NotificationCenter.default.removeObserver(self)
}
}
class OnClosureLeak : Leak {
override init() {
super.init()
_ = NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "OnFunctionLeak"),
object: nil,
queue: nil) { [unowned self] notif in
self.doNothing(notif)
}
}
func doNothing(_ notif: Notification) { }
deinit {
NotificationCenter.default.removeObserver(self)
}
}
var onFunctionLeak: OnFunctionLeak? = OnFunctionLeak()
onFunctionLeak = nil
//XCTAssertEqual(instanceCounter, 0)
print("instanceCounter: \(instanceCounter) == 0")
instanceCounter = 0
var onClosureLeak: OnClosureLeak? = OnClosureLeak()
onClosureLeak = nil
//XCTAssertEqual(instanceCounter, 0)
print("instanceCounter: \(instanceCounter) == 0")
短い方の選択肢がライン26上にあり、私は{ [unowned self] notif in self.doNothing(notif) }
でdoNothing
を交換する場合、強い参照がなくなっています。
アイデア?
関連する:「メソッドからのクロージャから強い参照サイクルを削除する方法」(http://stackoverflow.com/q/39899051/2976878)「自分自身への強い参照を避けるより良い方法があるとは思わない'あなたの2番目の例のようにクロージャを使わずに。 – Hamish
私はそれを読んで、私は確信しています。しかし、それが確認されれば、私の考えはなぜそれが常に隠れている強い参照を作成する場合は、質問を直接書くことができますので、簡単に間違いをすることができます。 – Dam
ところで、 "NotificationCenter.default.removeObserver(self)"を呼び出すことは、一般的に悪い習慣とみなされます。これは、親クラスを混乱させる可能性があるため、Appleはあなたの観測結果を1つずつ削除することをお勧めします。 –