主頁 > 移動端開發 > Dart異步Future與事件回圈Event Loop

Dart異步Future與事件回圈Event Loop

2020-12-14 07:10:54 移動端開發

如何使用異步Future

什么是異步

如果你的程式中有兩個方法,這兩個方法桉順序執行,第一個方法執行需要五秒,如果是同步代碼,第二個方法會等待第一個方法執行完,才會被呼叫,

如果第一個方法是異步的,程式在執行第一個方法時,不會等待它執行結束,而是接著執行第二個方法,這樣第二個方法就無需在第一個方法執行完之后被呼叫,

在客戶端異步是非常有用的,如果你在初始化時有一個非常耗時,但又不需要它在ui畫面回應前執行完成的方法,你就可以使用異步,

Dart異步處理庫Future

了解了異步的概念后,我們來看一看如何在Dart中使用異步,

    testFuture();
    testFuture2();
    
  Future testFuture() {
    //下面是一個耗時三秒的任務
    return Future.delayed(Duration(seconds: 3), () => print('異步方法'));
  }

  testFuture2() {
    print("普通方法");
  }

控制臺輸出

? 在這里插入圖片描述

將一個方法的回傳值宣告為Future這樣這個方法就是異步的了,

Future的構造方法

你也可以使用Future類的構造方法來使用異步

  Future(() {
      print('異步方法');
    });

Future類的構造方法如下

普通的Future類構造
Future(FutureOr<T> computation())

創建一個延遲幾秒執行的Future  duration引數來控制延遲多久
Future.delayed(Duration duration, [FutureOr<T> computation()])

通過微任務佇列處理的Future
Future.microtask(FutureOr<T> computation())

立即回傳結果的Future
Future.sync(FutureOr<T> computation())

Future.value([FutureOr<T>? value])

Future.error(Object error, [StackTrace? stackTrace])


構造方法演示

Future.delayed(Duration(seconds: 3), () => print('異步方法1'));
Future(() {
  print('異步方法2');
});
Future.microtask(() => print('異步方法3'));
Future.sync(() => print('異步方法4'));

控制臺輸出如下

在這里插入圖片描述

看到不同構造方法的執行順序,想必你已經對不同的構造方法有所了解

值得一提的是Future所有的構造方法回傳的都是Future物件,我們可以進行鏈式呼叫

Future的鏈式呼叫

當 future 執行完成后,then() 中的代碼會被執行,

Future(() {
  print('異步方法');
}).then((value) => print('異步方法2'));

等待多個 Future

有時代碼邏輯需要呼叫多個異步函式, 并等待它們全部完成后再繼續執行, 使用 Future.wait() 靜態方法管理多個 Future 以及等待它們完成:

Future deleteLotsOfFiles() async =>  ...
Future copyLotsOfFiles() async =>  ...
Future checksumLotsOfOtherFiles() async =>  ...

 Future.wait([
  deleteLotsOfFiles(),
  copyLotsOfFiles(),
  checksumLotsOfOtherFiles(),
]);

簡化Future

使用async和awiat來簡化異步代碼

這樣宣告一個方法 它就是異步的了

  testFuture5() async {
    Future.delayed(Duration(seconds: 3), () => print('異步方法1'));
  }

你也可以像寫同步代碼一樣使用異步,當在async宣告的方法中使用await時,async宣告的方法會等待await修飾的方法執行結束

  testFuture2() {
    print("普通方法");
  }
  
  testFuture5() async {
   await Future.delayed(Duration(seconds: 3), () => print('異步方法1'));
  }

  test()async{
   await testFuture5();
    testFuture2();
  }

控制臺輸出如下

image-20201213154650011

如果你對以上的默寫代碼執行順序有所疑惑,不要著急,下面的內容會解答你的所有問題,

事件回圈基本概念

本文描述了Dart的事件回圈架構,您就可以撰寫出更好的更少問題的異步代碼,您將學習如何使用Future,并且能夠預測程式的執行順序,

如果你寫過UI代碼,你可能已經熟悉了事件回圈和事件佇列的概念,它們確保了圖形操作和事件(如滑鼠點擊)一次只處理一個,

事件回圈和佇列

事件回圈的作業是從事件佇列中獲取一個事件并處理它,只要佇列中有事件,就重復這兩個步驟,

events going into a queue, feeding into an event loop

佇列中的事件可能代表用戶輸入,檔案I / O通知,計時器等, 例如,下面是事件佇列的圖片,其中包含計時器和用戶輸入事件:

same figure, but with explicit events: 1. key, 2.click, 3. timer, etc.

你可能在其他的語言中熟悉這些,現在我們來談談dart語言是如何實作的,

Dart的單執行緒

一旦一個Dart函式開始執行,它將繼續執行直到退出,換句話說,Dart函式不能被其他Dart代碼打斷,

如下圖所示,一個Dart程式開始執行的第一步是主isolate執行main()函式,當main()退出后,主isolate執行緒開始逐個處理程式事件佇列上的所有事件,
在這里插入圖片描述

實際上,這有點過于簡化了,

dart的事件回圈和佇列

Dart應用程式的事件回圈帶有兩個佇列——事件佇列和微任務佇列,

事件佇列包含所有外部事件:I/O、滑鼠事件、繪圖事件、計時器、Dart isolate之間的通信,等等,

微任務佇列是必要的,因為事件處理代碼有時需要稍后完成一個任務,但在將控制權回傳到事件回圈之前,例如,當一個可觀察物件發生變化時,它將幾個突變變化組合在一起,并同步地報告它們,微任務佇列允許可觀察物件在DOM顯示不一致狀態之前報告這些突變變化,

事件佇列包含來自應用程式中的事件,微任務佇列只包含來自Dart核心代碼的事件,

如下圖所示,當main()函式退出時,事件回圈開始作業,首先,它以FIFO(先進先出)順序執行所有微任務,然后,它使事件佇列中的第一項出隊并處理,然后它重復這個回圈:執行所有微任務,然后處理事件佇列上的下一事件,一旦兩個佇列都為空并且不會再發生任何事件,應用程式的嵌入程式(如瀏覽器或測驗框架)就可以釋放應用程式,

注意:如果web應用程式的用戶關閉了它的視窗,那么web應用程式可能會在其事件佇列為空之前強行退出,

flowchart: main() -> microtasks -> next event -> microtasks -> ...

重要:當事件回圈正在執行微任務佇列中的任務時,事件佇列會卡住:應用程式無法繪制圖形、處理滑鼠點擊、對I/O做出反應等,

盡管可以預測任務執行的順序,但不能準確預測事件回圈何時將任務從佇列中移除,Dart事件處理系統基于單執行緒回圈;它不是基于任何型別的時間標準,例如,當您創建一個延遲的任務時,事件將在您指定的時間進入佇列,他還是要等待事件佇列中它之前的所有事件(包括微任務佇列中的每一個事件)全部執行完后,才能得到執行,(延時任務不是插隊,是在指定時間進入佇列)

提示:鏈式呼叫future指定任務順序

如果您的代碼有依賴關系,請以顯式的方式撰寫,顯式依賴關系幫助其他開發人員理解您的代碼,并且使您的程式能方便的重構,

下面是一個錯誤編碼方式的例子:

// 因為在設定變數和使用變數之間沒有明確的依賴關系,所以不好,
future.then((){...設定一個重要變數...),
Timer.run(() {...使用重要變數...}),

相反,像這樣寫代碼:

//更好,因為依賴關系是顯式的,

future.then(…設定一個重要的變數…)

then((_){…使用重要的變數…});

在使用該變數之前必須先設定它,(如果您希望即使出現錯誤也能執行代碼,那么可以使用whenComplete()而不是then(),)

如果使用變數需要時間并且可以在以后完成,請考慮將代碼放在新的Future中:

//可能更好:顯式依賴加上延遲執行,

future.then(…設定一個重要的變數…)

then((_) {new Future((){…使用重要的變數…})});

使用新的Future使事件回圈有機會處理事件佇列中的其他事件,下一節將詳細介紹延遲運行的調度代碼,

如何安排任務

當您需要指定一些需要延遲執行的代碼時,可以使用dart:async庫提供的以下API:

Future類,它將一個專案添加到事件佇列的末尾,

頂級的scheduleMicrotask()函式,它將一個專案添加到微任務佇列的末尾,

使用這些api的示例在下一節中,事件佇列:new Future()和微任務佇列:scheduleMicrotask()

使用適當的佇列(通常是事件佇列)

盡可能的在事件佇列上調度任務,使用Future,使用事件佇列有助于保持微任務佇列較短,減少微任務佇列影響事件佇列的可能,

如果一個任務需要在處理任何來自事件佇列的事件之前完成,那么你通常應該先執行該函式,如果不能先執行,那么使用 scheduleMicrotask()將這個任務添加到微任務佇列中,

shows chain of event handler execution, with tasks added using Future and scheduleMicrotask().

事件佇列: new Future()

要在事件佇列上調度任務,可以使用new Future()或new Future.delayed(),這是dart:async庫中定義的兩個Future的建構式,

注意:您也可以使用Timer安排任務,但是如果Timer任務中發生任何未捕獲的例外,您的應用程式將退出, 相反,我們建議使用Future,它建立在Timer之上,并增加了諸如檢測任務完成和對錯誤進行回應的功能,

要立即將一個事件放到事件佇列中,使用new Future():

//在事件佇列中添加任務,

new Future((){

 /……代碼就在這里……

});

您可以添加對then()或whenComplete()的呼叫,以便在新的Future完成后立即執行一些代碼,例如,當new Future的任務離開佇列時,以下代碼輸出“42”:

new Future(() => 21)
    .then((v) => v*2)
    .then((v) => print(v));

使用new Future.delayed()在一段時間后在佇列中加入一個事件:

// 一段時間之后,將事件加入佇列
new Future.delayed(const Duration(seconds:1), () {
  // ...代碼在這里...
});

盡管前面的示例在一秒后將任務添加到事件佇列中,但該任務只有在主isolate空閑、微任務佇列為空以及之前在事件佇列中入隊的任務全部執行完后才能執行,例如,如果main()函式或事件處理程式正在運行一個復雜的計算,則任務只有在該計算完成后才能執行,在這種情況下,延遲可能遠不止一秒,

關于future的重要細節:

1 傳遞給Future的then()方法的函式在Future完成時立即執行,(函式沒有進入佇列,只是被呼叫了)

2 如果Future在呼叫then()之前已經完成,則將一個任務添加到微任務佇列,然后該任務執行傳遞給then()的函式,

3 Future()和Future.delayed()建構式不會立即完成; 他們將一個專案添加到事件佇列,

4 value()建構式在微任務中完成,類似于#2

5 Future.sync()建構式立即執行其函式引數,并且(除非該函式回傳Future,如果回傳future代碼會進入事件佇列)在微任務中完成,類似于#2,(Future.sync(FutureOr computation())該函式接受一個function引數)

微任務佇列:scheduleMicrotask()

async庫將scheduleMicrotask()定義為一個頂級函式,你可以像這樣呼叫scheduleMicrotask():

scheduleMicrotask(() {
  // ...代碼在這里...
});

dart2.9會將第一次呼叫scheduleMicrotask()時,將此代碼插入事件佇列的第一位

向微任務佇列添加任務的一種方法是在已經完成的Future上呼叫then(),有關更多資訊,請參閱前一節

必要時使用isolates 或workers

現在您已經閱讀了關于調度任務的所有內容,讓我們測驗一下您的理解,

請記住,您不應該依賴Dart的事件佇列實作來指定任務順序, 實作可能會發生變化,Future的then()和whenComplete()方法是更好的選擇, 不過,如果您能正確回答下面這些問題,你學會了,

練習

Question #1

這個示例列印出什么?

import 'dart:async';
void main() {
  print('main #1 of 2');
  scheduleMicrotask(() => print('microtask #1 of 2'));

  new Future.delayed(new Duration(seconds:1),
                     () => print('future #1 (delayed)'));
  new Future(() => print('future #2 of 3'));
  new Future(() => print('future #3 of 3'));

  scheduleMicrotask(() => print('microtask #2 of 2'));

  print('main #2 of 2');
}

答案

main #1 of 2
main #2 of 2
microtask #1 of 2
microtask #2 of 2
future #2 of 3
future #3 of 3
future #1 (delayed)

這個順序應該你能預料到的,因為示例代碼分三批執行:

1 main()函式中的代碼

2 微任務佇列中的任務(scheduleMicrotask())

3 事件佇列中的任務(new Future()或new Future.delayed())

請記住,main()函式中的所有呼叫都是從頭到尾同步執行的,首先main()呼叫print(),然后呼叫scheduleMicrotask(),再呼叫new Future.delayed(),然后呼叫new Future(),以此類推,只有回呼--作為 scheduleMicrotask()、new Future.delayed()和new Future()的引數代碼才會在后面的時間執行

Question #2

這里有一個更復雜的例子,如果您能夠正確地預測這段代碼的輸出,就會得到一個閃亮的星星,

import 'dart:async';
void main() {
  print('main #1 of 2');
  scheduleMicrotask(() => print('microtask #1 of 3'));

  new Future.delayed(new Duration(seconds:1),
      () => print('future #1 (delayed)'));

  new Future(() => print('future #2 of 4'))
      .then((_) => print('future #2a'))
      .then((_) {
        print('future #2b');
        scheduleMicrotask(() => print('microtask #0 (from future #2b)'));
      })
      .then((_) => print('future #2c'));

  scheduleMicrotask(() => print('microtask #2 of 3'));

  new Future(() => print('future #3 of 4'))
      .then((_) => new Future(
                   () => print('future #3a (a new future)')))
      .then((_) => print('future #3b'));

  new Future(() => print('future #4 of 4'));
  scheduleMicrotask(() => print('microtask #3 of 3'));
  print('main #2 of 2');
}

在這里插入圖片描述

dart程式會在第一次創建微任務佇列時,將創建微任務佇列的代碼插入到事件佇列的第一位,相當于插隊,

總結

你現在應該了解Dart的事件回圈以及dart如何安排任務,以下是Dart中事件回圈的一些主要概念:

Dart應用程式的事件回圈使用兩個佇列執行任務:事件佇列和微任務佇列,

事件佇列有來自Dart(futures、計時器、isolate messages)和系統(用戶操作、I/O等)的事件,

目前,微任務佇列只有來自Dart核心代碼的事件,如果你想讓你的代碼進入微任務佇列執行,使用scheduleMicrotask(),

事件回圈在退出佇列并處理事件佇列上的下一項之前先清空微任務佇列,

一旦兩個佇列都為空,應用程式就完成了它的作業,并且(取決于它的嵌入程式)可以退出,

main()函式和來自微任務和事件佇列的所有專案都運行在Dart應用程式的主isolates 上,

當你安排一項事件時,遵循以下規則:

如果可能,將其放在事件佇列中(使用new Future()或new Future.delayed()),

使用Future的then()或whenComplete()方法指定任務順序,

為了避免耗盡事件回圈,請保持微任務佇列盡可能短,

為了保持應用程式的回應性,避免在任何一個事件回圈中執行計算密集型任務,

要執行計算密集型任務,請創建額外的isolates 或者 workers,

參考文章:
https://dart.cn/articles/archive/event-loop#:~:text=A Dart app has a,queue and the microtask queue.&text=First, it executes any microtasks,item on the event queue.

https://api.dart.dev/stable/2.10.4/dart-async/Future-class.html

https://www.dartcn.com/guides/libraries/library-tour#future

文章中所有的測驗異步的代碼都在作者的github上,https://github.com/jack0-0wu/flutter_demo,

如果你對Dart flutter 計算機基礎感興趣可以關注作者,持續分享優質文章,
坐而論道不如起而行之

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/234200.html

標籤:其他

上一篇:Android全面決議之Window機制

下一篇:Android之window機制token驗證

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more