由於WKWebView使用的是多線程架構,渲染模塊和網絡模塊都各自在一個單獨的進程里面,因此,如果需要設置渲染模塊或者網絡模塊里面的斷點,需要做一些特殊處理。
舉個例子,假設在Xcode里面設置了渲染模塊里面一個函數的符號斷點:

如果像平時一樣,運行工程期待斷點生效是不可能的。這是因為默認情況下,這個斷點是在主進程,例子里面是TestWKServer進程,而主進程是沒有上面的RenderElement函數的,因此不會觸發斷點。
正確的操作是要將WKWebView的渲染進程和網絡進程Attach到Xcode里面。方法就是選擇Xcode的Debug菜單,然后選擇Attach to Process by PID or Name...或者Attach to Process。

選擇Attach to Process by PID or Name...需要填入進程的PID或者進程的名字,對於WKWebView的渲染進程和網絡進程來說,它們的名字分別是com.apple.WebKit.WebContent、com.apple.WebKit.Networking。
選擇Attach to Process會展開所有的進程列表,選擇需要Attach的進程就行。
那么,這兩種有什么差別呢?
由於Attach to Process需要被Attach的進程已經創建才行,但是我們有時候可能等進程被創建完畢才去Attach就會錯過斷點執行的時機,這時候Attach to Process by PID or Name...就會顯得很有用了。Attach to Process by PID or Name...在被Attach的進程還未創建時,就告訴Xcode:"我需要Attach這些進程,請在它們創建之后就立即Attach進來",這樣就不會錯過任何斷點時機了。
但是需要注意的是,由於你在調試的時候,可能開着諸如Safari一類的程序,由於Safari使用WKWebView,也會有渲染進程和網絡進程,當你通過Attach to Process by PID or Name...設置了需要Attach的進程名字,然后啟動你的工程,會發現Xcode確實Attach了渲染進程和網絡進程,但是Attach的確是Safari的而不是你自己的(因為Safari的渲染進程和網絡進程先於你的創建),這時候斷點也不會生效。
有兩種辦法解決上述問題:
1)退出Safari之類使用WKWebView的程序,確保除了自己的工程之外,不會有其他程序已經創建了WKWebView的渲染進程和網絡進程。確認的方式是使用Attach to Process提供的進程列表,確認里面沒有com.apple.WebKit.WebContent com.apple.WebKit.Networking進程;
2)使用Attach to Process,但是需要確保我們Attach的時候,程序還未執行我們想要斷點的函數。一個比較有用的方法是先在WKNavigationDelegate的- webView:decidePolicyForNavigationAction:preferences:decisionHandler:實現函數里面設置一個斷點,當斷到這個函數時,渲染進程和網絡進程已經創建,並且這兩個進程也還剛剛開始運行,一般來說,我們也來得及設置后續我們需要設置的斷點。這個時候就可以使用Attach to Process去Attach我們自己的渲染進程和網絡進程,一個好用的規律是我們自己的渲染進程和網絡進程是主進程的子進程,它們的PID非常相似(或者說相近),如果實在不確定哪個進程是我們自己的,就將列表里面所有的com.apple.WebKit.WebContent、com.apple.WebKit.Networking進程Attach進來,只是這樣比較繁瑣。
