當UIWebView播放視頻時,可以看到view hierarchy裡有FigPluginView的身影。這個類來自於QuickTime Plugin,plugin的路徑為:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Internet Plug-Ins/QuickTime Plugin.webplugin
這是個檔案夾,裡面還有連結庫以及檔案和圖片資源。QuickTime Plugin這個名字起得很響亮,其實代碼並不多,Objective-C類只有9個,也就只是FigPluginView為主了。與WebKit.framework有耦合,或者說就是為了封裝視頻播放控制項來給WebKit.framework用的。類別關係如:
UIWebDocumentView會以成員變數struct __CFDictionary *_plugInViews來配對FigPluginView和UIWebPlugInView,其中FigPluginView為key,UIWebPlugInView為value。
UIWebPlugInView有成員變數UIView *_uiView指向FigPluginView,
FigPluginView有成員變數WAKView *_wakView指向UIWebPlugInView。
當然,視頻只是PluginView的一種,UIWebPlugInView還會管理別的種類的plugin。
渲染流程中會有這樣的關係:
RenderLayerBacking在更新layer樹時,從RenderWidget出發通過幾層關係得到UIWebPlugInView,調用其函數attachPluginLayer把FigPluginView添加到UIWebDocumentView中。注意這個“添加”是通過好多層CALayer間接實現的,UIWebPlugInView還會建立一個hostLayer作為MediaLayer。調用鏈的末端實現代碼如下:
- (void)_connectPluginLayers{ WebThreadLock(); if (!_hostingLayer) { _hostingLayer = [[CALayer alloc] init]; } [_webView.layer insertSublayer:_hostingLayer atIndex:0]; if ([[_webView webView] _setMediaLayer:_hostingLayer forPluginView:self]) { self.parentedInLayer = YES; [_uiView retain]; [_hostingLayer addSublayer:_uiView.layer]; [_uiView release]; [_webView _setSubviewCachesNeedUpdate:YES]; [self _reshapeOnMainThread]; }}
這裡只列個大概了,類間網狀依賴,好難畫圖和用文字說明。總之可以更確定,WAKView就是替代了NSView,以求和Mac的WebView共用代碼,但iOS application是單進程程式,只能用CALayer樹來代替NSView樹做組合了。