「 iOS知識小集 」2018 · 第 37 期

知識小集發表於2018-11-19

原文連結

上週公眾號釋出的以下文章:

本期知識小集的主要內容包括:

  • Xcode 的 Build Settings 選中 Levels 時不同列的含義
  • Xcode 10.1 並沒有修復由於 Assets 引起的在 iOS 9 上的崩潰問題
  • Swift 4.2 MemoryLayout 新方法 offset(of:)

Xcode 的 Build Settings 選中 Levels 時不同列的含義

作者: KANGZUBIN

Build Settings 顧名思議,用於表示 Xcode 工程的編譯配置項。我們在 Xcode 工程中,開啟一個 Project 或者 Target 的 Build Settings 時,會得到如下圖所示,此時在頂部分欄中一般預設選中 AllCombined

「 iOS知識小集 」2018 · 第 37 期

其中,圖中左側紅框內的 BasicCustomizedAll 分別表示 基礎配置項已經自定義修改過的配置項全部配置項

而圖中右側的紅框內,有 CombinedLevels 兩項,我們最熟悉的是在 Combined 模式下,直接修改下方各配置項的值。

當我們選中 Levels 模式時,會得到如下圖所示:

「 iOS知識小集 」2018 · 第 37 期

我們發現,此時每一個配置項都對應了 4 列值(左側選中 Project 時只有 3 列;選中 Target 時有 4 列),分別為 ResolvedTargetNameProjectNameiOS Default。它們的含義如下:

  • iOS Default 列:Xcode 工程各編譯配置項的預設值,無法修改

  • ProjectName 列:用於配置 Project 的編譯配置項,它會影響其下的所有 Targets 的 Build Settings,優先順序高於iOS Default 列,可以手動修改

  • TargetName 列:用於配置某一 Target 的編譯配置項,優先順序高於 ProjectName 列,可以手動修改

  • Resolved 列:根據前面 3 列的優先順序關係,得到最終的值。它不可手動修改,優先取 TargetName 列的值,如果該列沒設定,則取 ProjectName 列的值,最後才取 iOS Default 列的預設值(Resolved 列的各項最終取的那一列的值,會被淺綠色框選高亮顯示)。

通過對比這幾列資料,你可以很清晰地看出我們都改了哪些預設配置,都是在哪改動的。其實我們可以發現,Resolved 列各項的值,就是選中 Combined 模式下,各配置項的值。

PS:在 Pods 工程中各 Targets 的 Build Settings 可

Xcode 10.1 並沒有修復由於 Assets 引起的在 iOS 9 上的崩潰問題

作者: KANGZUBIN

關於 Xcode 10.0 打的線上 Release 包會在 iOS 9.0 ~ 9.2.1 系統上出現隨機的崩潰,相信大家已經不陌生了,網上已有不少關於這個問題的討論

之前 @高老師很忙 也寫了一個小集《解決 Xcode 10 打包 iOS 9.0 - iOS 9.2.1 Crash 的問題》,分析了這個問題產生的原因,以及如何解決這個問題。

我們的 App 上個月一開始用 Xcode 10.0 發了一個包,因為這個導致線上崩潰率直線上升(主要集中在 iOS 9),無奈之下,只能用 Xcode 9.4.1 重新編譯發了一版本

蘋果號稱在 Xcode 10.1 Beta 2 中解決了這個問題,然後在 2018 年 10 月 31 日,蘋果釋出了 Xcode 10.1 正式版,並在 Release Notes 中聲稱已經解決了這個問題,有如下截圖為證:

「 iOS知識小集 」2018 · 第 37 期

然而,當天立刻有人在蘋果的開發者論壇(Apple Developer Forums)上發了帖子說這個問題仍然存在,

如下圖所示:

「 iOS知識小集 」2018 · 第 37 期

國內也有很多開發者通過自身 App 的實踐紛紛證實了這個問題。

我們 App 前幾天發新版,打包人員疏忽忘記了這個問題,直接用 Xcode 10.1 發包上線,結果這兩天果然在 iOS 9 上的崩潰率又上來了,慘痛教訓!!!

另外,讓人遺憾的是:蘋果已經偷偷在 Xcode 10.1 的 Release Notes 中,把這個問題從 Resolved Issues(已解決的問題)改為 Known Issues(已知問題)了,如下:

「 iOS知識小集 」2018 · 第 37 期

臨時解決方法:

  • 參考之前高老師的小集介紹的幾種方式
  • 切回到 Xcode 9.4.1 打包
  • 把 App 最低支援系統改為 iOS 10+ ...?
  • 等待 Xcode 10.2 解決 ...?

Swift 4.2 MemoryLayout 新方法 offset(of:)

在 Swift 4.2,MemoryLayout 引入是新方法 offset(of:),來計算結構體的某個儲存屬性的在記憶體佈局上到其所屬值的位元組距離,以替代 C 語言中的 offsetof 函式。

如下示例:

struct Point {
var x, y: Double
}

struct Size {
var w, h: Double

var area: Double { return w*h }
}

struct Rect {
var origin: Point
var size: Size
}

MemoryLayout<Rect>.offset(of: \.origin.x) // => 0
MemoryLayout<Rect>.offset(of: \.origin.y) // => 8
MemoryLayout<Rect>.offset(of: \.size.w) // => 16
MemoryLayout<Rect>.offset(of: \.size.h) // => 24
MemoryLayout<Rect>.offset(of: \.size.area) // => nil
複製程式碼

這個方法目前只支援結構體 struct,而不支援 tuple 和類型別。同時還有不少限制,如只能是儲存屬性,且不能有 didSetwillSet 等。

具體可以參考 swift evolution 210:Add an offset(of:) method to MemoryLayout

關注我們

歡迎關注我們的公眾號:iOS-Tips,也歡迎加入我們的群組討論問題。可以公眾號留言 iosflutter 等關鍵詞獲取入群方式。

「 iOS知識小集 」2018 · 第 37 期

推薦閱讀

「 iOS知識小集 」2018 · 第 36 期 「 iOS知識小集 」2018 · 第 35 期

相關文章