面试题答案
一键面试UIWebView设计模式特点
- 代理模式:通过
UIWebViewDelegate
协议,实现对网页加载、资源请求等事件的控制。例如,在webView:shouldStartLoadWithRequest:navigationType:
方法中决定是否允许网页加载。 - 消息传递模式:使用
stringByEvaluatingJavaScriptFromString:
方法与JavaScript交互,将JavaScript代码作为字符串传递并执行,获取返回值。
WKWebView设计模式特点
- 代理模式扩展:
WKNavigationDelegate
和WKUIDelegate
等协议,提供更细粒度的网页导航、界面交互控制。如webView:decidePolicyForNavigationAction:decisionHandler:
方法用于更灵活地决定导航策略。 - 基于JavaScriptCore框架的交互:采用
WKUserContentController
来注册JavaScript脚本消息处理程序,通过postMessage
在JavaScript与原生代码间传递消息,实现更高效的双向通信。
针对不同的优化策略及原理、实现步骤
1. 优化UIWebView性能
-
优化策略:减少JavaScript执行频率。
-
原理:频繁执行
stringByEvaluatingJavaScriptFromString:
会带来性能开销,因为每次执行都要进行字符串解析和JavaScript引擎交互。 -
实现步骤:
- 合并多个JavaScript操作,将多个相关操作合并成一个复杂的JavaScript语句执行。
- 缓存JavaScript执行结果,避免重复执行相同的JavaScript代码。
-
优化策略:优化网页加载过程。
-
原理:在
UIWebViewDelegate
中合理控制加载过程,避免不必要的资源加载。 -
实现步骤:
- 在
webView:shouldStartLoadWithRequest:navigationType:
方法中,根据请求的URL判断是否需要加载,如过滤广告资源等。 - 对于重复请求的资源,可以缓存并直接返回,而不重新加载。
- 在
2. 优化WKWebView性能
- 优化策略:优化JavaScript与原生交互。
- 原理:合理使用
WKUserContentController
注册消息处理程序,减少不必要的消息传递开销。 - 实现步骤:
- 批量处理JavaScript消息,在JavaScript端将多个相关消息合并成一个发送。
- 在原生代码中,对收到的消息进行高效处理,避免复杂的主线程操作。
- 优化策略:预加载网页。
- 原理:利用
WKWebView
的加载特性,提前加载可能需要访问的网页,提高用户体验。 - 实现步骤:
- 在合适的时机(如应用启动、空闲时段),使用
loadRequest:
方法加载可能访问的网页。 - 可以使用缓存策略,避免重复加载相同内容。
- 在合适的时机(如应用启动、空闲时段),使用
3. 提高两者可维护性
- 优化策略:统一交互逻辑。
- 原理:将JavaScript与原生交互的逻辑封装成独立模块,便于维护和修改。
- 实现步骤:
- 针对UIWebView和WKWebView分别创建交互管理类,封装与JavaScript交互的方法。
- 在业务代码中,通过调用这些封装好的方法进行交互,而不是直接操作WebView的相关接口。
- 优化策略:日志记录。
- 原理:在WebView的代理方法和交互逻辑中添加详细日志,方便排查问题。
- 实现步骤:
- 使用
NSLog
或专业日志框架(如CocoaLumberjack)记录WebView加载过程、交互消息等关键信息。 - 根据日志分析问题,如JavaScript错误、加载失败原因等。
- 使用
4. 提高两者稳定性
- 优化策略:错误处理。
- 原理:在代理方法中对各种可能出现的错误进行捕获和处理,防止应用崩溃。
- 实现步骤:
- 在UIWebView的
webView:didFailLoadWithError:
和WKWebView的webView:didFailProvisionalNavigation:withError:
等方法中,对加载错误进行处理,如提示用户或尝试重新加载。 - 对于JavaScript与原生交互过程中的错误,在接收消息处理方法中进行捕获和处理。
- 在UIWebView的
- 优化策略:内存管理。
- 原理:避免WebView使用过程中的内存泄漏,及时释放不再使用的资源。
- 实现步骤:
- 当WebView不再使用时,调用
removeFromSuperview
方法将其从视图层级移除,并将其设置为nil
。 - 对于WKWebView,在其加载完成后,可以释放一些与加载相关的临时资源。
- 当WebView不再使用时,调用