I am writing a simple metal app.
I tried to separate view and render. So I write a MTKViewDelegate class to to do render work and set the view's delegate to it. But it does not work. But when I make the view controller instance as the delegate, it works.
blow is my code
class ViewController: UIViewController,MTKViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let view = self.view as! MTKView
//view.delegate = self //this works,print 'drawing'
view.delegate = ViewController() //this does not work, not print anyting
print("view did load")
}
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
print("change size")
}
func draw(in view: MTKView) {
print("drawing")
}
}
Why this happens?
update
What I really meant was ,why when I set current instance of ViewController as view's delegate , it worked, but when I create a new instance, it did not work.
What I really want to do is making a render class to do render work as MTKView's delegate. But it did not work, so I test it with ViewController.
Thanks for matt's answer,I knew the reason is that , the delegate property of MTKView is weak referenced, so it could not hold the new created instance of MTKViewDelegate. The new created instance is recycled by garbage colletor.
What I need was just that the delegate property of MTKViewDelegate is 'weak'.When people do not notice this, the situation is confusing.
So,I think my question is valuable, and it's not like question Swift can't call protocol method via delegate. I think I should not be blocked to ask questions again.
The problem is that this line:
view.delegate = ViewController()
...makes a second ViewController, makes it the delegate
, and then throws it away.
You (the class containing this code) are the ViewController you want to be the delegate. So you need to say:
view.delegate = self
It works when you say that because self
is a persistent object. The other ViewController()
comes into existence and just vanishes again; it has no persistence so it can't do anything.
Why do you think it's wrong to say view.delegate = self
? It's normal and it works.