我有单一视图应用。 UINavigationViewController有一个根VC,里面有按钮。当pushVC从导航堆栈弹出时,它不会解除分配。 RootVC btnClick函数:
df=pd.DataFrame(columns=['a'])
df
Out[568]:
Empty DataFrame
Columns: [a]
Index: []
df2=pd.DataFrame(columns=['b', 'c', 'd'])
pd.concat([df,df2])
Out[571]:
Empty DataFrame
Columns: [a, b, c, d]
Index: []
pushVC有Notification Center订阅
@IBAction func btnClick(_ sender: Any) {
let vc = pushVC.init()
navigationController?.pushViewController(vc, animated: true)
}
log output:no deinit func called
class pushVC: UIViewController {
override func viewDidLoad() {
Log()
//this line brokes dealloc after pop from navigation stack
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "event_name"), object: nil, queue: nil) { (notification) in
self.printSomeText()
}
}
deinit {
Log()
}
func printSomeText() {
Log()
}
}
public func Log(filename: String = #file, line: Int = #line, funcname: String = #function) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm:ss:SSS"
let file = filename.components(separatedBy: "/").last!
print("[\(dateFormatter.string(from:Date())) \(file)(\(line)) \(funcname)] ->")
}
如果删除self.printSomeText(),则VC deinit按预期调用。
[16:50:44:321 pushVC.swift(16) viewDidLoad()] ->
[16:50:53:938 pushVC.swift(16) viewDidLoad()] ->
[16:56:52:909 pushVC.swift(16) viewDidLoad()] ->
[16:56:54:248 pushVC.swift(16) viewDidLoad()] ->
[16:56:55:655 pushVC.swift(16) viewDidLoad()] ->
self.printSomeText()行有什么问题? 它会保留自己吗?
答案 0 :(得分:1)
更新您的addObserver
以防止视图控制器自行保留...
override func viewDidLoad() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "event_name"), object: nil, queue: nil) { [weak self] notification in
self?.printSomeText()
}
}
你还应该让Notification.Name
对其他对象可见,删除deinit
上通知的观察者,并且最好拨打super.viewDidLoad()
...
extension NSNotification.Name {
static let eventName = NSNotification.Name("event_name")
}
class pushVC: UIViewController {
var observer: NSObjectProtocol?
deinit {
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
override func viewDidLoad() {
super.viewDidLoad()
observer = NotificationCenter.default.addObserver(forName: .eventName, object: nil, queue: nil) { [weak self] notification in
self?.printSomeText()
}
}
}