得物H5容器野指針疑難問題排查 & 解決
得物 iOS 4.9.x 版本 上線后,一些帶有橫向滾動內容的h5頁面,有一個webkit 相關crash增加較快。通過Crash堆棧判斷是UIScrollview執行滾動動畫過程中內存野指針導致的崩潰。
2、前期排查通過頁面瀏覽日志,發現發生崩潰時所在的頁面都是在h5 web容器內,且都是在頁面的生命周期方法viewDidDisappear方法調用后才發生崩潰,因此推測崩潰是在h5 頁面返回時發生的。
【資料圖】
剛好交易的同事復現了崩潰證實了我們的推測。因此可以基本確定:崩潰的原因是頁面退出后,頁面內存被釋放,但是滾動動畫繼續執行,這時崩潰堆棧中scrollview的delegate沒有置空,系統繼續執行delegate的相關方法,訪問了已經釋放的對象的內存(野指針問題)。
同時發生crash h5 頁面都存在一個特點,就是頁面內存在可以左右橫滑的tab視圖。
操作手勢側滑存在體驗問題,左右橫滑的tab視圖也會跟著滾動(見下面視頻)。關聯bugly用戶行為日志,判斷這個體驗問題是和本文中的crash有相關性的。
3、不完美的解決方案經過上面的分析,修復思路是在h5頁面手勢側滑返回時,將h5容器頁面內tab的橫滑手勢禁掉(同時需要在 h5 web容器的viewWillAppear方法里將手勢再打開,因為手勢側滑是可以取消在返回頁面)。
具體代碼如下(這樣在操作頁面側滑返回時,頁面的手勢被禁掉,不會再滾動):
@objc dynamic func webViewCanScroll(enable:Bool) { let contentView = self.webView.scrollView.subviews.first { view in if let className = object_getClass(view), NSStringFromClass(className) == "WKContentView" { return true } return false } let webTouchEventsGestureRecognizer = contentView?.gestureRecognizers?.first(where: { gesture in if let className = object_getClass(gesture), NSStringFromClass(className) == "UIWebTouchEventsGestureRecognizer" { return true } return false }) webTouchEventsGestureRecognizer?.isEnabled = enable }@objc dynamic func webViewCanScroll(enable:Bool) { let contentView = self.webView.scrollView.subviews.first { view in if let className = object_getClass(view), NSStringFromClass(className) == "WKContentView" { return true } return false } let webTouchEventsGestureRecognizer = contentView?.gestureRecognizers?.first(where: { gesture in if let className = object_getClass(gesture), NSStringFromClass(className) == "UIWebTouchEventsGestureRecognizer" { return true } return false }) webTouchEventsGestureRecognizer?.isEnabled = enable }
經過測試,h5 web容器側滑時出現的tab頁面左右滾動的體驗問題確實被解決。這樣既可以解決體驗問題,又可以解決側滑離開頁面導致的崩潰問題,但是這樣并沒有定位crash的根因。修復代碼上線后,crash量確實下降,但是每天還是有一些crash出現,且收到了個別頁面極端操作下偶現卡住的問題反饋。因此需要繼續排查crash根因,將crash根本解決掉。
繼續看文章開始的crash堆棧,通過Crash堆棧判斷崩潰原因是UIScrollview執行滾動動畫過程中回調代理方法(見上圖)時訪問被釋放的內存。常規解決思路是在退出頁面后,在頁面生命周期的dealloc方法中,將UIScrollview的delegate置空即可。WKWebView確實有一個scrollVIew屬性,我們在很早的版本就將其delegate屬性置空,但是崩潰沒有解決。
deinit { scrollView.delegate = nil scrollView.dataSource = nil }deinit { scrollView.delegate = nil scrollView.dataSource = nil }
因此崩潰堆棧里的Scrollview代理不是這里的WKWebView的scrollVIew的代理。那崩潰堆棧中的scrollView代理到底屬于哪個UIScrollview呢?幸運的是蘋果webkit 是開源的,我們可以將webkit源碼下載下來看一下。
4、尋找崩潰堆棧中的ScrollViewDelegate崩潰堆棧中的ScrollViewDelegate是WKScrollingNodeScrollViewDelegate。首先看看WKWebView的scrollview的 delegate是如何實現的,因為我們猜想這個scrollview的delegate除了我們自己設置的,是否還有其他delegate(比如崩潰堆棧中的WKScrollingNodeScrollViewDelegate)。
通過對Webkit源碼一番研究,發現scrollview的初始化方法:
- (void)_setupScrollAndContentViews{ CGRect bounds = self.bounds; _scrollView = adoptNS([[WKScrollView alloc] initWithFrame:bounds]); [_scrollView setInternalDelegate:self]; [_scrollView setBouncesZoom:YES];}- (void)_setupScrollAndContentViews{ CGRect bounds = self.bounds; _scrollView = adoptNS([[WKScrollView alloc] initWithFrame:bounds]); [_scrollView setInternalDelegate:self]; [_scrollView setBouncesZoom:YES];}
WKWebView的scrollVIew 是WKScrollView 類型。
4.1 WKScrollView 代理實現首先看到WKWebView的scrollview的類型其實是WKScrollView(UIScrollview的子類),他除了繼承自父類的delegate屬性,還有一個internalDelegate屬性,那么這個internalDelegate屬性是不是我們要找的WKScrollingNodeScrollViewDelegate 呢?
@interface WKScrollView : UIScrollView@property (nonatomic, assign) WKWebView *internalDelegate;@end@interface WKScrollView : UIScrollView@property (nonatomic, assign) WKWebView *internalDelegate;@end
通過閱讀源碼后發現不是這樣的(代碼有刪減,感興趣可自行閱讀源碼)。
- (void)setInternalDelegate:(WKWebView *)internalDelegate{ if (internalDelegate == _internalDelegate) return; _internalDelegate = internalDelegate; [self _updateDelegate];}- (void)setDelegate:(id )delegate{ if (_externalDelegate.get().get() == delegate) return; _externalDelegate = delegate; [self _updateDelegate];}- (id )delegate{ return _externalDelegate.getAutoreleased();}- (void)_updateDelegate{//...... if (!externalDelegate) else if (!_internalDelegate) else { _delegateForwarder = adoptNS([[WKScrollViewDelegateForwarder alloc] initWithInternalDelegate:_internalDelegate externalDelegate:externalDelegate.get()]); [super setDelegate:_delegateForwarder.get()]; }}- (void)setInternalDelegate:(WKWebView *)internalDelegate{ if (internalDelegate == _internalDelegate) return; _internalDelegate = internalDelegate; [self _updateDelegate];}- (void)setDelegate:(id )delegate{ if (_externalDelegate.get().get() == delegate) return; _externalDelegate = delegate; [self _updateDelegate];}- (id )delegate{ return _externalDelegate.getAutoreleased();}- (void)_updateDelegate{//...... if (!externalDelegate) else if (!_internalDelegate) else { _delegateForwarder = adoptNS([[WKScrollViewDelegateForwarder alloc] initWithInternalDelegate:_internalDelegate externalDelegate:externalDelegate.get()]); [super setDelegate:_delegateForwarder.get()]; }}
這個internalDelegate的作用是讓WKWebView 監聽scrollview的滾動回調,同時也可以讓開發者在外部監聽WKWebView的scrollview回調。如何實現的呢?可以查看WKScrollViewDelegateForwarder的實現。
- (void)forwardInvocation:(NSInvocation *)anInvocation{ //... if (internalDelegateWillRespond) [anInvocation invokeWithTarget:_internalDelegate]; if (externalDelegateWillRespond) [anInvocation invokeWithTarget:externalDelegate.get()];}- (void)forwardInvocation:(NSInvocation *)anInvocation{ //... if (internalDelegateWillRespond) [anInvocation invokeWithTarget:_internalDelegate]; if (externalDelegateWillRespond) [anInvocation invokeWithTarget:externalDelegate.get()];}
通過復寫- (void)forwardInvocation:(NSInvocation *)anInvocation 方法,在消息轉發時實現的。
4.2 猜想 & 驗證既然WKScrollingNodeScrollViewDelegate 不是WKScrollview的屬性,那說明崩潰堆棧中的scrollview不是WKScrollview,那頁面上還有其他scrollview么。我們看源碼WKScrollingNodeScrollViewDelegate 是在哪里設置的。
void ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren(const ScrollingStateScrollingNode& scrollingStateNode){ //...... if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::ScrollContainerLayer)) { if (!m_scrollViewDelegate) m_scrollViewDelegate = adoptNS([[WKScrollingNodeScrollViewDelegate alloc] initWithScrollingTreeNodeDelegate:this]); } }void ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren(const ScrollingStateScrollingNode& scrollingStateNode){ //...... if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::ScrollContainerLayer)) { if (!m_scrollViewDelegate) m_scrollViewDelegate = adoptNS([[WKScrollingNodeScrollViewDelegate alloc] initWithScrollingTreeNodeDelegate:this]); } }
搜索webkit的源碼,發現創建WKScrollingNodeScrollViewDelegate的位置只有一處。但是webkit的源碼太過于復雜,無法通過閱讀源碼的方式知道WKScrollingNodeScrollViewDelegate屬于哪個scrollview。
為此我們只能換一種思路,我們通過xcode調試的方式查看當前webview加載的頁面是否還有其他scrollview。
頁面上剛好還有一個scrollview:WKChildScrollview
這個WKChildScrollview 是否是崩潰堆棧中的scrollview呢,如果我們能確定他的delegate是WKScrollingNodeScrollViewDelegate,那就說明這個WKChildScrollview 是崩潰堆棧中的scrollview。
為了驗證這個猜想,我們首先找到源碼,源碼并沒有太多,看不出其delegate類型。
@interface WKChildScrollView : UIScrollView @end@interface WKChildScrollView : UIScrollView @end
我們只能轉換思路在運行時找到WKWebView的類型為WKChildScrollView的子view(通過OC runtime & 視圖樹遍歷的方式),判斷他的delegate是否為WKScrollingNodeScrollViewDelegate 。
我們運行時找到類型為 WKChildScrollView 的子view后,獲取其delegate類型,確實是WKScrollingNodeScrollViewDelegate。至此我們找到了崩潰堆棧中的scrollview。
確定了崩潰堆棧中的scrollview的類型,那么修復起來也比較容易了。在頁面生命周期的viewDidAppear方法里,獲取類型為 WKChildScrollView的子view。然后在dealloc方法里,將其delegate置空即可。
deinit { if self.childScrollView != nil { if self.childScrollView?.delegate != nil { self.childScrollView?.delegate = nil } }}deinit { if self.childScrollView != nil { if self.childScrollView?.delegate != nil { self.childScrollView?.delegate = nil } }}
4.3 小程序同層渲染想完了解決方案,那么WKChildScrollView 是做啥用的呢?
WKWebView 在內部采用的是分層的方式進行渲染,它會將 WebKit 內核生成的 Compositing Layer(合成層)渲染成 iOS 上的一個 WKCompositingView,這是一個客戶端原生的 View,不過可惜的是,內核一般會將多個 DOM 節點渲染到一個 Compositing Layer 上,因此合成層與 DOM 節點之間不存在一對一的映射關系。當把一個 DOM 節點的 CSS 屬性設置為overflow: scroll(低版本需同時設置-webkit-overflow-scrolling: touch)之后,WKWebView 會為其生成一個WKChildScrollView,與 DOM 節點存在映射關系,這是一個原生的UIScrollView的子類,也就是說 WebView 里的滾動實際上是由真正的原生滾動組件來承載的。WKWebView 這么做是為了可以讓 iOS 上的 WebView 滾動有更流暢的體驗。雖說WKChildScrollView也是原生組件,但 WebKit 內核已經處理了它與其他 DOM 節點之間的層級關系,這一特性可以用來做小程序的同層渲染。(「同層渲染」顧名思義則是指通過一定的技術手段把原生組件直接渲染到 WebView 層級上,此時「原生組件層」已經不存在,原生組件此時已被直接掛載到 WebView 節點上。你幾乎可以像使用非原生組件一樣去使用「同層渲染」的原生組件,比如使用view、image覆蓋原生組件、使用z-index指定原生組件的層級、把原生組件放置在scroll-view、swiper、movable-view等容器內等等)。
5、蘋果的修復方案本著嚴謹的態度,我們想是什么導致了最開始的崩潰堆棧呢?是我們開發過程中的功能還是系統bug?如果是系統bug,其他公司也可能遇到,但是互聯網上搜不到其他公司或開發者討論崩潰相關信息。我們繼續看一下崩潰堆棧的top 函數RemoteScrollingTree::scrollingTreeNodeDidScroll() 源碼如下:
void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingTreeScrollingNode& node, ScrollingLayerPositionAction scrollingLayerPositionAction){ ASSERT(isMainRunLoop()); ScrollingTree::scrollingTreeNodeDidScroll(node, scrollingLayerPositionAction); if (!m_scrollingCoordinatorProxy) return; std::optional layoutViewportOrigin; if (is(node)) layoutViewportOrigin = downcast(node).layoutViewport().location(); m_scrollingCoordinatorProxy->scrollingTreeNodeDidScroll(node.scrollingNodeID(), node.currentScrollPosition(), layoutViewportOrigin, scrollingLayerPositionAction);}void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingTreeScrollingNode& node, ScrollingLayerPositionAction scrollingLayerPositionAction){ ASSERT(isMainRunLoop()); ScrollingTree::scrollingTreeNodeDidScroll(node, scrollingLayerPositionAction); if (!m_scrollingCoordinatorProxy) return; std::optional layoutViewportOrigin; if (is(node)) layoutViewportOrigin = downcast(node).layoutViewport().location(); m_scrollingCoordinatorProxy->scrollingTreeNodeDidScroll(node.scrollingNodeID(), node.currentScrollPosition(), layoutViewportOrigin, scrollingLayerPositionAction);}
崩潰在這個函數里,查看這個函數的commit記錄:
簡單描述一下就是scrollingTreeNodeDidScroll方法中使用的m_scrollingCoordinatorProxy 對象改成weak指針,并進行判空操作。這種改變,正是解決m_scrollingCoordinatorProxy 內存被釋放后還在訪問的方案。
這個commit是2023年2月28號提交的,commit log是:
[UI-side compositing] RemoteScrollingTree needs to hold a weak ref to the RemoteScrollingCoordinatorProxyhttps://bugs.webkit.org/show_bug.cgi?id=252963rdar://105949247Reviewed by Tim Horton.The scrolling thread can extend the lifetime of the RemoteScrollingTree via activity on that thread,so RemoteScrollingTree needs to hold a nullable reference to the RemoteScrollingCoordinatorProxy;use a WeakPtr.[UI-side compositing] RemoteScrollingTree needs to hold a weak ref to the RemoteScrollingCoordinatorProxyhttps://bugs.webkit.org/show_bug.cgi?id=252963rdar://105949247Reviewed by Tim Horton.The scrolling thread can extend the lifetime of the RemoteScrollingTree via activity on that thread,so RemoteScrollingTree needs to hold a nullable reference to the RemoteScrollingCoordinatorProxy;use a WeakPtr.
至此,我們基本確認,這個崩潰堆棧是webkit內部實現的一個bug,蘋果內部開發者最終使用弱引用的方式解決。
同時修復上線后,這個crash的崩潰量也降為0。
6、總結本文中的crash從出現到解決歷時近一年,一開始根據線上日志判斷是h5 頁面返回 & h5 頁面滾動導致的問題,禁用手勢后雖然幾乎解決問題,但是線上還有零星crash上報,因此為了保證h5 離線功能的線上穩定性,需要完美解決問題。
本文的crash 似曾相識,但是經過驗證和閱讀源碼后發現并不是想象的那樣,繼續通過猜想+閱讀源碼的方式尋找到了崩潰堆棧中的真正scrollview代理對象,從而在app 側解決問題。最后發現是蘋果webkit的bug。
本文中的崩潰問題本質上是野指針問題,那么野指針問題定位有沒有通用的解決方案呢?
標簽:
推薦
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
索尼全新PS掌機Q將問世:10年沒更新這條產品線了 天天快資訊
2023-05-30 05:01:16 作者:人寶寶本周,索尼發布了一款名為“Project Q”的PlayStation掌上設備。不
來源: -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
財富更多》
-
全球最資訊丨金碚:挖掘工業機器人產業潛力
金碚:挖掘工業機器人產業潛力---一段時...
-
最大“黑客帝國”非美莫屬-頭條
最大“黑客帝國”非美莫屬---近日,有美...
-
“以我為主”釋放市場化改革效能
“以我為主”釋放市場化改革效能---作為...
-
一張精工“面膜”背后的“獨門絕技”|當前快報
一張精工“面膜”背后的“獨門絕技”---...
-
“白發姑蘇”傳承煥新——二千五百年古城的人文經濟嬗變
“白發姑蘇”傳承煥新——二千五百年古...
動態更多》
熱點
- realme10系列正式宣布 采用雙曲面屏正面頂部居中挖孔
- 五菱全新微型電動車內飾官圖發布 座椅采用星際形打孔工藝
- 努比亞Z40星空典藏版正式開售 采用微米級油畫筆觸紋理技術
- iQOO11系列正式官宣 首批搭載驍龍8Gen2機型之一
- 海信34英寸帶魚屏顯示器發布 支持165Hz刷新率
- OPPO明年將商用240W超級閃充 新一代電芯支持更高倍率充電
- 第一款Android手機渲染圖曝光 橫向滑蓋設計和全尺寸鍵盤
- 吉利首款純電皮卡11月9日上市 車輛續航里程超過610公里
- 努比亞Z40SPro星空典藏版正式公布 堪稱窄邊框天花板
- vivo無線運動耳機2今日正式上市 首銷只要119元
- 最強進化_對于最強進化簡單介紹
- 互動 北汽藍谷:目前SiC電機控制器已經處于研轉產的階段 正在進行第三輪可靠耐久測試_熱推薦
- 【世界快播報】溫暖“童”行,長壽這場培訓教你如何贏得孩子的心!
- 環球快資訊丨旬月在古文是什么意思_古文的旬是什么意思
- 銀魂哪一集是神威出場_銀魂第三季神威出場了嗎|全球快看點
- 戀愛恐懼癥的癥狀_戀愛恐懼癥的24個表現 戀愛恐懼癥有什么表現
- 微動態丨力爭突破100億元!2023臨沂實施水利項目工程數量及投資額均居全省第一
- 證明信的格式及范文調職_證明信的格式及范文
- 快消息!講歷史的節目誰講得好(講歷史的節目)
- 后搖音樂代表作_后搖音樂
- “杭州傘” “玉琮館” 這些亞運場館科技感爆棚_天天微資訊
- 焦點消息!中國信通院“OSCAR合規治理沙龍”在京召開 騰訊、阿里等企業共話開源生態建設
- 當前動態:基金調研丨Harding Loevner基金調研漢鐘精機
- 當前觀點:最新!河南要求:優先保住小麥種子、落實跨區機收免費通行......
- 中超:深圳勝梅州客家
- 天天時訊:情感與現實:探秘斯皮爾伯格如何通過電影讓人深思人生
- 北京檢察機關依法對周茂非涉嫌貪污、受賄案提起公訴
- 直播預告:今日中午專家教你居家推拿治療頸腰椎病?|環球快播
- 福建進一步加強房地產項目預售資金監管 違規企業將暫停銷售
- 瀘水縣氣象臺發布高溫橙色預警信號【Ⅱ級/嚴重】【2023-05-29】 天天滾動
- 皇社十年的等待!久保建英發文慶祝:歐冠,我們來啦!
- 天孚通信:控股股東擬減持公司不超0.75%股份
- 迎接賽末沖刺階段!
- 天天百事通!棲霞建設: 棲霞建設持股5%以上股東集中競價減持股份計劃時間屆滿暨結果公告
- 小舞成神造型終于來了,頭發完全散開,身穿白色蕾絲樣子仙哭|視焦點訊
- 世界熱文:海賊王:收視率最高的一集,只因娜美這這位侍女的迷之走光!
- 環球熱推薦:海水環境質量總體保持穩定 2022年我國海洋生態環境狀況穩中趨好
- 618職場福利!華為HarmonyOS 3 double職場生產力|環球播報
- 世界快資訊:一餓就心慌渾身無力發抖需要治療嗎(一餓就心慌渾身無力發抖)
- 當虹科技與三六零集團簽約:開展內容審核項目合作|全球時訊
- 土耳其第一次舉辦總統選舉第二輪投票 充滿了不確定性 全球聚看點
- 最新快訊!36氪晚報丨波音將在零部件供應鏈等領域與越南合作;渣打與普華永道中國聯合發布白皮書;五糧液參股創投企業投資新能源公司
- 經濟日報:為農機跨區作業提供有溫度的服務|當前訊息
- 無人駕駛礦山運輸機器人"載山CarMo"正式投入使用|焦點滾動
- 天天熱點評!吉林省前4月規上工業快速增長
- 波士頓咨詢公司報告:中國時尚行業將呈現量穩質升趨勢
- eFishery 完成規模為1.08億美元的D輪融資,軟銀等參投
- 講述“這一屆”職場人的故事
- 新增多項實用功能,廣汽傳祺影酷迎新版本OTA升級-全球資訊
- 環球新消息丨V觀財報|張家界收年報問詢函:為何凈利潤連續三年虧損?
- 隆基5月單晶硅片價格公示 平均價格下調約30%
- 深圳時尚家居設計周圓滿閉幕,德國 88 年品牌樂德飛翼
- 工業富聯漲6.6% 機構凈賣出7.15億元
- 環球觀速訊丨兩部門:推動大企業加強計量引領帶動,促大中小企業融通發展
- 華電國際漲停 機構凈買入1.76億元
- 戴威美國二次創業項目陷入困境:資金鏈受阻 擴張徹底停滯 天天速讀
- 焦點滾動:布吉人民醫院婦科怎么樣 布吉婦科醫院
- 焦點快看:報告稱2025年中國分布式存儲市場規模將超200億元
- 臺灣5月消費者信心指數回升 學者指“反映短期效應”
- iPhone16Pro機型為6.3和6.9英寸,屏幕加大只因這個組件 焦點播報
- 每日熱文:18元一斤?消費者大呼西瓜貴了 一小塊瓜要5元
- 廢鋼跌勢趨緩,跟隨成材運行
- 硅動力6月5日上交所首發上會 擬募資6.9億元|速遞
- 全球快播:少年中國問丨量子計算如何改變我們的生活?
- 江西移動與南昌市人民政府深化戰略合作
- 思密達全新劑型蒙脫石混懸液上市
- 微信:治理個人帳號發布違禁品營銷信息行為 世界觀速訊
- 東方通跌15.64% 機構凈賣出7416萬元_天天即時看
- 航錦科技跌9.57% 機構凈賣出9469萬元 短訊
- 全球視點!光子芯片溫控耗能減至目前的百萬分之一 可用于未來數據中心和超級計算機通信網絡
- 2023中關村論壇|精彩繼續 中關村國際技術交易大會不落幕 天天看熱訊
- 工行淮安城北支行貫徹學習二十大“四輪驅動”推進網點競爭力提升_實時焦點
- 生態環境部:穩步擴大火電、鋼鐵等行業碳監測評估
- 北京海淀區20所中小學授牌“非遺傳承基地校”
- 科技部火炬中心黨委書記呂先志:去年177家國家高新區園區生產總值占國內GDP比重13.9%_全球信息
- 觀熱點:文遠知行獲ISO/SAE 21434汽車網絡安全流程認證
- 工信部:1-4月份我國軟件業務收入33166億元,同比增長12.8%
- 北京米揚麗格夏正義院長:關于舒鉑材料的臨床實踐 暨纖鉑新品上市
- 為什么現在的演唱會都不能選位置?|全球訊息
- 清肺排毒湯_清肺
- 切瓦特·埃加福特加盟《毒液3》 漫威再就業 天天資訊
- 米蘭鎖定前四,皮奧利用人釋放信號:有人急需挽留,有人放棄治療
- 不屑,姆巴佩突爆爭議采訪!皇馬底蘊成笑話,佛爺知道C羅多好了
- HKC惠科發布首款QHD 500Hz顯示器:40-500Hz可變高刷、雙百色域 全球簡訊
- 天合光能跌16.34% 機構凈賣出4.52億元
- 環球熱門:Patient21獲得1.08億美元C輪融資
- 天津港集團與ABB公司簽署戰略合作協議|環球熱文
- 世界簡訊:渝北雙鳳橋街道:做好燃氣自閉閥安裝工作 筑牢群眾生命安全防線
- 特斯拉聲明:目前沒有與任何第三方進行招聘活動-每日訊息
- 觀天下·美債危機|媒體和業內人士:美國債務上限協議達成未必是“好消息”_天天簡訊
- 觀天下!通富微電漲10% 機構凈買入3.3億元
- 華為開發者大會2023 ( Cloud ) 將于7月7日正式揭幕-微動態
- 高三備考好兄弟Brother DCP-T426W打印機
- 最高法、全國婦聯發布保護未成年人權益司法救助典型案例 環球報道
- 鵬都農牧跌9.95% 機構凈賣出5105萬元
- 教師辦公必備好物Brother DCP-B7535DW打印機
- 花旗銀行開戶條件門檻_花旗銀行開戶條件
- 榮耀90系列全新發布,全系標配2億像素寫真相機影像升維_當前熱門
- 每日精選:開發“在線預約”,創新旅游業服務 在家“動動手”,出游更省心
- 臺北電腦展上英偉達(NVDA.US)公布了哪些產品和服務?-天天視點
- 滾動:18年前失蹤兒子,線索斷裂
- 榮耀90系列全新發布,全系標配2億像素寫真相機影像升維_焦點快播
- 百度地圖2023年第一季度中國城市交通報告:廣東人通勤出行最幸福|環球速看
- 全球今亮點!吳若曼新任興銀基金董事長兼法定代表人 張貴云離任
- 每日精選:電影《長空之王》香港票房超11萬美元
- 兩部門聯合印發《關于實施中小企業計量伙伴計劃的通知》
- 第25屆上海國際電影節金爵獎入圍影片名單揭曉 速讀
- 當前視點!現代和起亞宣布與FIFA的合作伙伴關系延長至2030年
- 天天新動態:平安基金成鈞離任2只ETF
- 國投瑞銀瑞盛混合(LOF)增聘基金經理賀明之 全球熱頭條
- 中微電科技完成新一輪融資-全球速訊
- 每日看點!Checkmate.獲得1500萬美元A輪融資
- 匯豐晉信基金副總經理兼首席運營官趙琳離任|實時
- 當前快看:醫療冷鏈有哪些股票?醫療冷鏈概念股票一覽
- 世界今日訊!光伏組件概念股名單一覽(2023A股光伏組件概念上市公司)
- 光伏發電投資額同比大增 機構看好光伏設備高景氣
- 環球動態:神舟十五號乘組即將返回 創出艙次數最多等多項紀錄
- 世界今日報丨海洛創新獲千萬元Pre-A輪融資
- 視頻解析工具Video-ChatGPT上線 可用文本描述視頻內容 世界新動態
- Sabi Am獲得3800萬美元B輪融資
- 競賽聚英才 第二屆"長江杯"動力電池技術挑戰賽決賽開幕
- 租房難?一德國男子使用ChatGPT 找到滿意的房子 全球微資訊
- 業界:提升農業社會化服務水平 讓小農戶融入大產業大市場_世界關注
- 【環球時快訊】收評:創業板指跌1.14% 電力板塊全天強勢
- 【當前熱聞】全國首個無人島島主成“老賴” 名下海島起價2785萬流拍
- 天天快看:種地吧出品方申請后陡門商標 種地吧出品方申請十個勤天商標
- 天天觀熱點:次北固山下的意思簡短一點_次北固山下的意思簡介介紹
- 全球看點:議論“校園碾壓案”家長妝容,這是無聊更是殘忍
- 當前快播:豆瓣8.1,這世界也容不下男孩的親密友誼
- 搞了半天,高德打車無證卻變相從事網約車經營,一喂等平臺吃瓜了
- 華為發布商業市場新品,助力數字化轉型_每日播報
- 寶馨科技攜新能源領域多項最新研發和應用成果亮相SNEC展會 每日熱點
- 外媒:特斯拉數據或“大規模”泄露,涉及馬斯克信息-全球消息
- Orbofi AI獲得280萬美元戰略投資-全球聚看點
- 潤貝航科(001316):該股換手率大于8%(05-29)-聚看點