國慶小集團隊休息了兩週,現在我們又回來了。整裝待發,後面我們努力為大家帶來更多更好的文章。
上週公眾號釋出的以下文章:
本期知識小集的主要內容包括:
- 利用 GCD 訊號量將非同步方法改造為同步方法
- 提高開發效率 --- UI 部分
- WKWebView 使用 WKWebViewJavascriptBridge 需要注意的地方
- 開源庫使用的 Clang __attributes__
利用 GCD 訊號量將非同步方法改造為同步方法
作者: halohily
有的時候,我們會遇到一個同步方法(該方法的所有工作在返回之前已全部完成)的內部實現,需要依賴其他非同步過程的情況。比如介面定義了一個開啟聊天會話的方法,返回值為布林值。從返回值型別不難推測,我們希望這個方法返回之時,會話是否開啟成功就已經確切得知。然而,開啟會話的內部實現僅僅是向服務端發起連線請求,是否連線成功需要等待服務端的響應,顯然這是一個非同步的過程。這就是一個常見的非同步過程需要改造為同步(對外表現同步)的場景。如何實現呢?可以採用 GCD 的訊號量:發起連線請求之前,建立一個初始值為 0 的訊號量,在方法返回之前請求該訊號量(P 操作),同時,在連線請求的結果回撥中釋放該訊號量(V 操作)。這樣,發起連線請求後,由於訊號量初始值為 0,會阻塞在請求訊號量的地方,連線請求回撥回來之後,釋放訊號量,剛剛的訊號量請求被滿足,方法得以返回。這樣對外表現即為一個同步且耗時的開啟會話操作,雖然這個場景比較彆扭,但與此類似的情景是很常見的。
在大家熟知的 AFNetworking 中,就有這樣的應用:
提高開發效率 --- UI 部分
作者: Lefe_x
最近在探索可以提高開發效率的方法,目前先從 UI 方面入手,旨在能夠快速的建立 UI,避免做不斷重複的工作,現初步找到幾種方法並開始實踐,希望對你能夠有啟發,如果你有更好的想法,歡迎分享給我:
- 使用檔案模板:對於某些重複性比較大的 ViewController,可以通過定義模板,這樣建立 ViewController 的時候直接使用模板建立,會節省一部分時間;如果有一套自己建立 UI 的命名規則,還會節省一部分時間,模板程式碼越多,就越少寫多餘的程式碼;
- 使用程式碼片段:對於一些小功能,比如建立某個 Label,某個屬性;如果定義成程式碼片段,也會節約一部分時間;有了程式碼片段,那麼寫程式碼就是成段成段的寫,這裡需要注意定義程式碼片段時命名規則,避免由於忘記程式碼片段的名字浪費查詢的時間;
- 積累自己的UI庫:其實很多 UI 在其它專案中已經寫過了,如果平時注重積累,那麼很多 UI 直接搬過來既可以使用,這裡寫 UI 時要記得解耦,UI 部分儘量不要與專案耦合,這樣複用性更強;
- 統一管理 UIColor:一個 APP 中常用的顏色就那麼幾種,這些顏色使用 Color set 統一管理,優點就是你不需要不斷地看某個字型的顏色是什麼,某個 view 的背景顏色是什麼,直接呼叫已經建立的顏色即可,比如:
+ (UIColor *)lef_blackColor;
- 使用Sketch:你往往會抱怨 UI 切的圖,標記的位置並不是你想要的,反覆的和 UI 要切圖,要顏色,如果使用好 Sketch 這個工具,很多圖你自己都可以搞定,不過有的 UI 使用的是 PS 那就尷尬了;
- 系統學習 UI 知識:當你花了好大力氣實現某個 UI 效果後,發現系統提供了一個 API,一句話就實現了,心裡一萬個草泥馬,你所謂遇到的坑,往往就是沒有系統地學習 UI 的原理,導致遇到莫名其妙的問題不知如何下手。
WKWebView 使用 WKWebViewJavascriptBridge 需要注意的地方
原生端與 H5 端互動,比較常用的就是 WebViewJavascriptBridge。建橋過程這邊不再贅述,只要下載 Github 上的 Demo 參考即可,OGitHub - marcuswestin/WebViewJavascriptBri...。
注意點一:Run 以後會捕捉到一個 Crash,在官網的 Demo 裡同樣會有這個 Crash,如圖一。這個 Crash 只有在用 WKWebView 裡會出現,用 UIWebView 是好的。
解決方法:在 WKWebViewJavascriptBridge.m
檔案line 150 後面加一行程式碼。如圖二。參考 issue :github.com/marcuswesti… 。不知為何,作者沒有合併該 issue,原始碼裡也未修復。因此用 cocoapods 整合庫的同學,每次 pod install 後要檢查原始碼中是否有新增上述一行程式碼。
注意點二:註冊 bridge 後,與 H5 的互動無法成功。
解決方法:檢查一下 H5 小夥伴程式碼裡有沒有圖三程式碼段落。這一段 js 程式碼是不能改的,需原樣複製。檢視原始碼發現,在 WKWebViewJavascriptBridge.m
檔案 line 135 方法中,[_base injectJavascriptFile]
是注入 js 檔案,也是互動的關鍵。在執行這行程式碼之前,有 [_base isBridgeLoadedURL:url]
這個判斷,點進去檢視該判斷的實現,發現兩個巨集 kCustomProtocolScheme
和 kBridgeLoaded
,分別對應 @"wvjbscheme"
和@"__BRIDGE_LOADED__"
。 這也就跟圖三程式碼中的 WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
對上了。
開源庫使用的 Clang __attributes__
作者: Vong_HUST
今天和大家分享一下第三方開源庫使用到的一些實用的 Clang attributes
。
圖1出自 PSPDFUIKitMainThreadGuard
————一個用於檢測是否在非主執行緒呼叫 UI 相關的工具,使用的是 __attribute__((constructor)),被該修飾符修飾的函式(僅對 C 函式生效),會在 main 函式之前執行,但是稍微比 +load 晚一點,因為 dyld 呼叫完 image 中所有類的 load 方法之後才會呼叫 image 中的 constructor。這個修飾符支援優先順序的設定,如 __attribute__((constructor(1024))),其中 1~100 為系統保留。
下面程式碼出自 YYModel,修飾符 __inline__ __attribute__((always_inline)) 意味著強制內聯,什麼意思呢?就是它看起來是一個函式,但是編譯的時候,會被編譯器優化,相當於把函式體內程式碼直接插入到被呼叫的地方,這樣就避免掉了一些壓棧、返回等操作,加快呼叫。
當然系統也有很多巨集是對 Clang attributes 的封裝,一些系統封裝巨集程式碼如下,更多例子可以自行檢視系統標頭檔案。
參考連結:
- blog.sunnyxx.com/2016/05/14/…
- vongloo.me/2017/04/21/…
- gcc.gnu.org/onlinedocs/…
- blog.twitter.com/engineering…
- nshipster.com/__attribute…
關注我們
歡迎關注我們的公眾號:iOS-Tips,也歡迎加入我們的群組討論問題。可以公眾號留言 ios
、flutter
等關鍵詞獲取入群方式。