【发布时间】:2016-11-04 18:24:27
【问题描述】:
将方法传递给采用闭包的函数时,我可以使用 someFunc(closure: someMethod) orsomeFunc() { [unowned self] in self.someMethod() }`。
第一个较短,但具有很强的参考意义。如何在避免这种强引用的同时使用它?
这是一个演示,其中包含泄漏的一个和好的一个: 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 行,如果我将 doNothing 替换为 { [unowned self] notif in self.doNothing(notif) },那么强引用就消失了。
有什么想法吗?
【问题讨论】:
-
相关:How to remove strong reference cycle from closure from method? 我认为没有更好的方法可以避免在不使用闭包的情况下对
self进行强引用,例如在您的第二个示例中。 -
我读过它并要求确定。但是如果被证实了,我的想法是如果它总是会创建一个隐藏的强引用,那么为什么允许直接写这个问题,那么容易出错。
-
顺便说一句,调用“NotificationCenter.default.removeObserver(self)”通常被认为是不好的做法——这可能会弄乱父类,因此 Apple 鼓励您一一删除您的观察结果。
标签: swift function closures strong-references