彈指間就來到秋風颯爽的九月

新專案上線也過了兩三個月

新功能的開發都沒有什麼問題

因為大部分的需求

都可以參照過往的經驗

在期限內完成

唯一一個遇到比較麻煩的

應該就是壞在Application main 的例外

起因是串接同事的模組專案

從source tree 拉下來merge

重新build完程式碼

發現一開App就會立馬閃退

以往解決的方式

當然是看壞在哪一行

這次卻是壞在Application等級

用白話來說

就是不知道程式碼錯在哪一行

處理起來就相對棘手

既然不知道壞在哪裡

就只能土法煉鋼

一行一行下中斷點

看跑到哪一行會閃退

最後發現是在實體化主頁

也就是tabViewController時閃退

不過看了半天還是沒發現問題所在

再來就是第二步了

把tab頁面所連接的每個分頁都拔掉

就神奇的「正常運作」了

不會閃退但是畫面是空白的

Debug第三步

就是再把分頁

逐一連回tabViewController

第一頁連上,重run成功

第二頁連上,重run成功

第三頁連上,重開閃退

兇手就藏在第三頁的程式碼裡

當下懷疑是三方套件的問題

把三方的code註解掉之後

想說OK了

按下run之後往後伸個懶腰

沒想到還是閃退

嚇得我又彈回螢幕前

竟然不是三方問題

似乎還聽得到閃退元凶的隱隱嘲笑聲

前三個步驟從結果回推原因

沒有辦法找出答案

於是我換個方式

想一下造成問題的源頭

是這一次的merge code

問了同事這次的修改內容

其中有一個是變更backend專案的bundle name

再對照壞掉分頁的程式碼

發現有一個用bundle實體化的元件

還使用舊的bundle name所以導致閃退

改完bundle名稱後就天下太平了

為了這個字串

前前後後花了五六個小時

解完真的是覺得心累

這一個月還有一件大事

就是去參加2019 iPlayground

因為同時間最多有三堂講座

手機組派出三個人聽課

聽完回來後要做報告

和大家分享

今年的主題滿多的

包括MVC MVVM的架構

加快編譯速度

最潮的Car play Apple watch等等

還有資安或是網路套件的框架實現

今年有許多主題是講最新的Swift UI

號稱要推翻(?)OC舊有的UIKit

看完只有一個結論:

Still broken

加上釋出不久後

卻災情不斷的iOS 13

搭配更不穩定的XCode 11

目前看起來離普及使用還有一大段距離 

再來與實務工作最相關的

就是加快編譯速度啦

最粗暴的方式就是花錢

買一台最新的mac

聽起來很蠢但是卻很實際

要求老舊電腦編譯速度

和新電腦一樣

無疑癡人說夢

不過講者當然不只提到這個

加快編譯速度其實分滿多層次的

從最基本的不要在debug時

生成dsym檔案

編譯時不要選擇whole module

也不要進行最佳化

再到更進階的

把新的Code 寫到framework裡面

編譯時只編譯framework

甚至使用三方框架BUCK

定義編譯連結規則

加速大型專案的編譯速度

端看專案架構規模適合哪種方式

另外一個受益良多的就是各種架構的解說

從MVC,MVVM到MVVMC

以及從網頁來的「Viper」

講者解釋這些流派的由來

以及要解決的問題是什麼

像是MVVM就是要解決MVC當中的

ViewController負擔過重的問題

也就是所謂的「Massive」ViewController

而MVVMC比起MVVM

多了一個控制流程的coordinator

把頁面跳轉的邏輯

從viewController抽出來

講了這麼多架構

不是要強調誰比較好

而是要選擇適合自己專案的架構

第二天的Keynote請到大名鼎鼎的王巍

演講題目是「網路難,難於上青天」

從頭開始講起如何建立一個網路請求的框架

包括最基礎的Get Post

如何簡化共用帶參數的程式碼

到最麻煩的錯誤處理

例如網路層的405,500錯誤

或是回傳的資料解析失敗

如果要寫得精簡

真的就如同題目所說的

難於上青天

有關iPlayground的課程影片以及筆記

都有公開在網路上

算是真的滿佛心的

這個月下班又開始閒閒的

去附近各個圖書館晃一圈

看到一本64位元組合語言

久聞Assembly大名

就拿回家研究一下

比起C語言

組合語言又更貼近底層了

像是暫存器的應用

對於堆疊的指標控制

都是以前沒看過的神奇操作

當初想要了解組合語言

本來就不是要去寫韌體

而是理解電腦的底層運作

知道我們平常寫的程式

被編譯成組合語言後

電腦是如何處理這些程式碼

由於貼近底層的關係

在寫程式時可以直接使用cpu內的暫存器

比起存取記憶體的資料又快上不少

不過同時就要考慮許多問題

像是參數的傳遞

該使用什麼樣的呼叫慣例

是stdcall,cdecl還是fastcall

參數是從左至右

還是從右至左推入堆疊

由呼叫者(caller)或是被呼叫者(caller)清理堆疊

函示的return值是存在哪一個暫存器等等

寫完組語後

還要寫批次檔案

呼叫Linker把目的檔案連結起來

產生可執行檔

不過說老實話

看完之後有百分之八十的內容都一知半解

有疑問的地方也沒有人可以請教

畢竟現在軟體公司

應該沒有人上班還在寫組語的

可能還是要真人教學才會知道在幹嘛

最後附上組合語言的Hello world

雖然很像複製貼上

但真的是一個字一個字打出來的

在這邊留做一個紀念

Extern scanf, printf

SECTION .data
msg DB ‘Hello, World’, 0
fmt DB ‘%s’

SECTION .text
start:

PUSH RCX
PUSH RDX
MOV RDX, msg
MOV RCX, fmt 
SUB RSP, 32
CALL printf
ADD RSP, 32
POP RDX
POP RCX

RET