原文連接html
上週公衆號發佈的如下文章:ios
本期知識小集的主要內容包括:c++
做者: 高老師很忙git
悲劇的背景是這樣的:有一個較早時間註冊的AppleID,因爲對本身記憶力的過度自信,沒有備份安全問題,並以前只在網頁端登陸過,沒有在手機端登陸過,而且沒有填寫過手機號和其餘郵箱,各類找回安全問題的路都被堵死了。在嘗試了N次輸入錯誤答案,帳號被鎖了N次後,只能寄但願於蘋果爸爸幫我順利登陸。github
聯繫上蘋果技術支持,他們告訴我他們沒有權限處理這類問題,並建議我好好回憶一下答案多嘗試幾回或者聯繫開發者支持試試;shell
開發者支持的電話實在太難打進去了,打了2天才打進去,獲得的結果仍然是他們沒有權限幫我處理,建議我開啓雙重認證,安全問題就自動廢除了。安全
那麼就又出現了一個新的難題,開啓雙重認證須要回答安全問題,感受進入了一個死循環。。。。繼續給蘋果打電話,他們告訴我能夠重置手機,激活的時候登陸AppleID,放置幾天,而後再在手機端開啓雙重認證,會跳過回答安全問題的步驟,問其緣由,工做人員說他們也不清楚,這也不是官方作法,只是有人這樣成功過,抱着試一試的心態,果真這個辦法有效,之後仍是好好備份纔是王道呀!架構
做者: KANGZUBINapp
一般,咱們的 Xcode 工程會依賴一些第三方庫,包括:.a 靜態庫(Static Library)和 .framework 動態庫(Dynamic Library)。函數
不過簡單地把 .framework 後綴的文件稱爲「動態庫」並不嚴謹,由於在 iOS/macOS 開發中,framework 又分爲靜態 framework 和 動態 framework,區別以下:
靜態 framework
:能夠理解爲是 .a 靜態文件
+ .h 公共頭文件
+ 資源文件
的集合,本質上與 .a 靜態庫是一致的;
動態 framework
:即真正意義上的動態庫,通常包括動態二進制文件、頭文件和資源文件等。
對於一個 Static Library 工程,其編譯產物爲 .a 靜態二進制文件 + 公共 .h 頭文件;
對於一個 Framework 工程,其編譯的最終產物是動態庫仍是靜態庫,咱們能夠經過在 Build Settings -> Linking -> Mach-O Type 中進行選擇設置其值爲 Dynamic Library
或者 Static Library
。
此外,咱們知道,對於一個 Mach-O 二進制文件,不論是 static 仍是 dynamic,通常都包含了幾種不一樣的處理器架構(Architectures),例如:i386, x86_64, armv7, armv7s, arm64 等。
Xcode 在編譯連接時,對於靜態庫和動態庫的處理方式是不一樣的。
對於靜態庫,在連接時(Linking Time),Xcode 會自動篩選出靜態庫中的不一樣 architecture 合併到對應處理器架構的主可執行二進制文件中;而在打包歸檔(Archive)時,Xcode 會自動忽略掉靜態庫中未用到的 architecture,例如會移除掉 i386, x86_64 等 Mac 上模擬器專用的架構。
而對於動態庫,在編譯打包時,Xcode 會直接拷貝整個動態 framework 文件到最終的 .ipa 包中,只有在 App 真正啓動運行時,纔會進行動態連接。可是蘋果是不容許最終上傳到 App Store Connect 後臺的 .ipa 文件包含 i386, x86_64 等模擬器架構的,會報 Invalid 錯誤,因此對於工程中的動態 framework,咱們在打 Release 正式包時,通常會經過執行命令或者腳本的方式移除掉這些 Invalid Architectures。
最後,如何在 Xcode 工程中添加這些靜態/動態庫呢?
對於 「.a 靜態庫」 和 「靜態 framework」 ,直接拖拽到工程中,並勾選 Copy if needed
選項便可,無需其餘設置;而對於添加「動態 framework」,稍微比較麻煩,咱們將在下一條小集介紹幾種不一樣的方法。
以上,但願對你能有所幫助,不足之處,歡迎指出。
做者: KANGZUBIN
在上一條小集,咱們分別介紹了 「.a 靜態庫」、「靜態 framework」 和 「動態 framework」 的異同。
接下來咱們將介紹一下,如何在 Xcode 工程中添加動態庫(Dynamic Library)。
首先咱們知道,對於 「.a 靜態庫」 和 「靜態 framework」,直接把相關文件拖拽到工程中,並勾選 Copy if needed 選項便可,無需其它額外的設置;
而對於添加「動態 framework」,稍微比較麻煩,主要有如下幾種方式。
PS:咱們這裏說的「添加動態庫」是指第三方動態庫,而不是像 UIKit.framework、Foundation.framework 或者 libc++ 等系統自帶的動態庫,對於它們的依賴添加很簡單,直接在 General -> Linked Frameworks and Libraries 中點擊加號搜索添加便可。
在 Xcode 工程中選中 app 對應的 target,而後在 General -> Embedded Binaries 下點擊加號,如圖 1,在彈出的窗口選擇 Add Other...,最後在 Finder 中選擇你要添加的「動態 framework」,並勾選 Copy if needed 便可。須要注意的是,你不能直接在 Finder 中把 .framework 文件拖拽到 Embedded Binaries 中,不然會報錯。
關於手動添加動態庫的更多細節以及遇到問題的解決辦法,可參考蘋果官方的教程:《Embedding Frameworks In An App》
可是!這種方式看似很方便,其實有個坑是:咱們上一條小集提到,通常動態二進制文件都會包含不少處理器架構,例如:i386, x86_64, armv7, armv7s, arm64 等,而後 Xcode 在編譯連接時,對動態二進制文件是直接拷貝到 .ipa 包中,並不會像連接靜態庫那樣篩選掉未用到 architecture,而蘋果又不容許把包含 i386, x86_64 等模擬器架構的包上傳到 App Store Connect 後臺,會報錯。所以,咱們在打 Release 正式包時每每須要手動經過 lipo 命令或者編寫腳本移除掉這些 Invalid Architectures。(除非你的開發工程只經過真機來調試,不許備在模擬器裏運行,且添加的動態庫恰好又不包含 i38六、x86_64)
對於經過 Carthage 集成的第三方庫,在 Cartfile 文件中添加好依賴後,而後執行 carthage update
命令會幫咱們生成一個個「動態 framework」,例如 AFNetworking.framework、SDWebImage.framework 等,而後把它們拖拽到工程中,詳細可參考 Carthage 的 Quick Start 教程。
這裏有個關鍵操做是,須要在 Xcode 工程的 Build Phases 中添加一個執行腳本(New Run Script Phase),並在腳本中執行以下命令:
/usr/local/bin/carthage copy-frameworks
複製代碼
該命令的做用大概就是,在打包拷貝動態庫時自動幫咱們移除掉其中的 i38六、x86_64。
一樣地,經過 CocoaPods 集成動態庫時,也會在工程中自動幫咱們添加一個 Shell 腳本用於作這件事,如圖 2 中的 [CP] Embed Pods Frameworks,你們能夠自行查閱該 Pods-xxx-frameworks.sh 腳本的內容,裏面有個函數 strip_invalid_archs()
就是用於在打包時移除無用的處理器架構。
所以,咱們能夠把本身開發的或者他人提供的動態 framework,經過 CocoaPods 來集成到工程中:建立一個 Pods 私有 git 庫(相信你們已經很熟悉了),在 git 庫中添加相關動態 .frameworks 文件,而後其 Podspec 文件的寫法大體如圖 3 所示,最後在你的工程中 pod install
便可。
最後咱們思考一個問題:「靜態 framework」 和 「動態 framework」 在使用上彷佛也沒什麼不一樣,而工程添加 「動態 framework」 又比較繁瑣,那麼在 iOS/macOS 開發中什麼狀況下會使用動態庫呢?
做者: 夏天是一隻貓巛
如 NSMachPort。另外自定義的類實現了 allowsWeakReference/retainWeakReference
實例方法返回 NO(默認返回YES)也不能用 __weak
修飾。allowsWeakReference
返回 NO 後,使用後會異常終止。以下圖:
使用 retainWeakReference
返回 NO 後不會崩潰,可是 __weak
值爲null,以下圖。也能夠在在該方法內部控制對象的 weak 次數。
歡迎關注咱們的公衆號:iOS-Tips,也歡迎加入咱們的羣組討論問題。能夠公衆號留言 ios
、flutter
等關鍵詞獲取入羣方式。