Optional

Optional 正如其名,就是個可選擇或者說是可有可無的意思。

在 Swift 的開發過程之中,我們可以看到「 ! 」、「 ? 」存在於變數之後,像是  var userName: String? 正式意味著 userName 這個 String 有可能是 nil。

有關 Swift optional 的解釋和 nil 對於 Swift 的介紹可以看看這篇,由小草哥所攥寫的文章。

這邊要補充的是,在 Objective-C 裏頭,則是使用 nonnull 和 nullable 來代表著 Swift 裡頭的「 ! 」、「 ? 」。

而在 Objective-C 之中,可以使用 NS_ASSUME_NONNULL_BEGIN 及 NS_ASSUME_NONNULL_END 來作為區域性的宣告 @property 的屬性為 nonnull;若其中有需要宣告成 nullable 的,則再補上即可。

七天學會設計模式 – Facade

其實 Facade 的概念簡單來說,就是簡化使用物件方的介面。

舉個例來說,我建立了一個 Calendar 的 UICollectionView,可能裡頭會需要很多的邏輯判斷;像是「計算 Cell 的 Size」、「判斷日期是否為假日」、「判斷月份」⋯⋯等,但使用這個物件的人,基本上不需要(也不應該)去煩惱這些事情。

如同我們吹電風扇,只需要「強、中、弱、關」的使用介面,並不需要知道它內部是調整不同的功率去達到這效果,但對使用者而言並不是那麼的重要。

而在 MVC 的架構底下便是如此,使用者只需要 ViewController 上可以操作的 function 即可,底部的 Model 是如何操作以及邏輯運算如何,就相對的沒那麼重要,丟給系統去做就好!

所以在 Facade 的設計模式下,每個物件的介面需要被規劃過,哪些需要使用 private、fileprivate、class 等,適時地分配各個變數或常數及方法的使用權限。

七天學會設計模式 – Observer

訂閱

有使用過網誌或是一些新聞類型的網站時,通常可以在旁邊看到「訂閱」的按鈕,接著點擊下去後就可以在作者有發動或異動文章時,收到通知。

Observer

這個設計模式的概念類似於「訂閱」的功能,我們會去「訂閱」某個物件,當它做了某些事情或者其值改變時,可以去做相對應的動作。

應用

舉個比較常會遇到的案例:鍵盤

我們通常會希望在鍵盤升起來時,調整我們的畫面,看是移動 View 的 frame,或是設定 TableView 的 ContentOffset 之類的。

而大多數採取的方式是「監聽」 NotificationCenter 的「鍵盤升起」的事件,所以當「鍵盤升起」時,我們可以做相對應的處理;而當「鍵盤收起」時,我們也可以執行另一段 function。

這,便是 Observer 的設計模式。

我們去「訂閱」或者「監聽」某個事件,像是 Value changed 或是某個 function 被呼叫,來做相對應的處理。

第三方套件

RxSwiftReactiveCocoa 便都是圍繞在 Observer 設計模式的框架,來做響應式的開發。

響應式開發

如名稱所述,意思是指當 Model 或者 ViewModel 的狀態(值)更動時,畫面可以很即時地跟著變動。

對 RxSwift 有興趣的人,可以看看這篇文章 線上讀書會 RxSwift 影片分享

Weak?

在 iOS 的開發語言之中,不論是 Objective-C 或者 Swift,你或許都有看過這個詞

weak

你可能會知道它可以避免 retain cycle,但其背後的觀念是什麼?

ARC

在目前大家所熟悉的開發環境之中,記憶體的管理是由 iOS 或 macOS 自行去解決的;它會在你宣告或者呼叫物件的時候,替它在計數器上 +1,而當你用不到時,便會 -1。

當計數器為零的時候,便釋放掉這個物件的記憶體位置。

舉個例子,我在某個 ViewController 裏頭,宣告了一個變數 A 及執行一個異步的閉包(closure),並在裡頭使用到 A。

此時,A 在剛剛宣告產生的時候,計數器會是 +1,而在閉包內被使用到,故計數器會再 +1,所以在閉包執行時,它會是 2。

那如果我們這時候,離開了 ViewController,照理說其裡頭的 instance 應該都要被釋放記憶體位置;但因為異步閉包的關係,我們無法確定在離開的時候,異步閉包是否在其他執行緒中正在執行,造成 A 的計數器仍為 1,且會繼續執行異步閉包的內容。

 

weak 簡單來說就是,它並不會讓這個物件在計數器上 +1,並且在記憶體被釋放之後,指標會指向 nil;而在 Objective-C 及 Swift 裏頭,nil 的物件呼叫方法時,是不會造成崩潰的。

retain cycle 就像是 A 使用到 B,並且 B 也使用到 A,兩者互相幫對方在計數器上 +1,那僅管我們今天離開了這個畫面,系統幫 A – 1 之後,仍然會因為 B 有使用到它,故釋放不掉 A,而 A 有使用 B,所以 B 也釋放不掉。(很饒舌,我知道)

所以在 A 裡頭使用到 B 時,將 B 宣告成 weak B,便不會幫 B 在計數器上記上一筆;當 A 要被釋放掉的時候,也不會因為 B 使用 A,而釋放不掉。

502 Bad Gateway Error with nginx

源頭

在攥寫「七天學會設計模式 – Singleton」時,發生了點小狀況。

我點擊 WordPress 的「全部文章」時,顯示 502 Bad Gateway 的錯誤訊息;

由於點下去後不久(一、兩秒內)就跳轉出錯誤,故猜測不是 timeout 的關係,

便開始了一段 debug 的故事⋯⋯

環境

我是使用 WordPress(不是重點)的框架,並架設在 Vultr 的主機上;

主機的主要規格為 CPU 1 vCore、RAM 1024 MB、25 GB SSD。

 

原因

透過 nginx 的 error log(cat /var/log/nginx/wordpress_https_error.log)

發現關鍵字:

upstream sent too big header while reading response header from upstream

拿去餵狗的結果是,需要調整 nginx.conf(vim /etc/nginx/nginx.conf),

加上

來調整 buffer size,來避免資源不足直接捨棄的情況(502)。

由於 5 塊美金的方案,Vultr 僅提供 1024 MB 的記憶體大小,但它有 25 GB 的 SSD!

故可以透過 Swap 的方式,用硬碟換取記憶體的效能。

依序輸入完後,可以輸入「free」來看 swap 是否有使用相對應的 size 了!

便可以解決 nginx 因資源不足所產生的 502 Bad Gateway error!

[心得] 工作一年半的一些心得分享

前陣子在 Ptt MacDev 版上寫了一篇心得:

各位好,這篇文章主要是給新手一些方向和想法~

純屬個人的經歷和看法,可以一起以輕鬆的態度聊聊~

我個人是在 2015 年中開始接觸 iOS 的開發,以 Objective-C 為一開始自學方向。 從簡單遊戲開始下手,像是猜數字、圈圈叉叉之類的, 練練基本的拉拉 UI、認識Storyboard、.h 的宣告、.m 的實作等。

接著剛好 Xcode 7 開始讓免費的開發者可以裝 App 至實體裝置上, 發現自己原本都用 4.7 吋的模擬器執行,而到了 5.7 吋的裝置上時, 會有跑版的問題,於是花了一些時間學習 AutoLayout。

而基本上 AutoLayout 有個概念熟悉即可, 除非是比較特別的效果需要思考一下彼此之間的 priority, 不然一般 App 都還蠻輕易解決這方面的問題; 而比較有趣的是,像在 ScrollView 裏頭做 AutoLayout 時, 要有 contentSize 的概念,而不要輕易的點「讓系統補完 constraints」的按鈕。

接著,在我準備面試前的一兩個月,加入了一些 iOS 的開發社群 (e.g iOS @ Taipei、Cocoaheads Taipei等) 厚著臉皮加了版上比較活躍的幾位前輩,並詢問他們一些問題和方向, 於是開始練習其他實作:

練習接 Api,當時我是寫了一個去接目前各雨量觀測站的 App, 篩選 10 分鐘內有偵測到雨量的, 並在 MapView 上放上大頭針,顯示當區目前雨量。 (AFNetworking、MapKit)

  • QR Code 掃瞄器

當初瘋狂失敗的原因在於模擬器無法執行打開相機的功能, 一開就會報 Crash,而後來在裝到手機上才發覺當初懊惱的自己有多傻XD 不過這也學到了要好好 Google 的一課, 畢竟後來想想這明明是很簡單下的關鍵字,且網路上很多人會告訴你這件事…

  • 縣市的各學校地址清單

而因為當時有這需求,便寫了一個可以讀特定格式的資料, 然後畫面簡單地透過 UINavigationController 控制前後頁, 跳轉到縣市 -> 鄉鎮 -> 學校 -> 資訊等, 練習一下 ViewController 間的切換和流程安排。

  • 午餐電話簿

結合上述所學(不包含 QR Code), 便寫了一個會先判斷離自己最近的雨量偵測站是否有偵測到 10 分鐘內下雨, 來作為篩選依據(下雨的話就只隨機挑選有外送的), 隨機挑選後並可以決定是否今天要吃XD 再透過 FMDB 的方式記錄下來成清單,告訴自己這幾天都吃什麼… (很無聊的功能,就只是想練習 FMDB)

而上述都有使用到一些第三方套件,也選擇了 Cocoapods 來做管理。 於是我便拿著這些沒什麼商業價值的小工具上台北面試了… 很幸運的是,在面了兩間之後,就拿到其中一間的 Offer, 便開始了以 iOS 作為工作的生活。

接著在這一年半左右的時間,開始寫 Swift(報到的第一天被告知要寫 Swift XDDDDD) 學習 ViewController 的生命週期,也體會到 Storyboard 和 Xib 之間的優缺點, 甚至用 Code 直接刻 View 的好處等。

很多事情都要等你真的遇到了,才會很深刻地體會到, 為什麼當初有些前輩會這樣建議你… 而自己在這段時間又玩了 Parse、Firebase、Fastlane、Fabric、Carthage, 以及和 Android 之間透過 Bonjour 聯繫之類的一些不是太重要的技能XDD

看似沒什麼重點的文章,想告訴新人們的是一句我從 iOS @ Taipei 聚會中聽來的觀念: 「在這領域的知識累積,並非是線性的成長,而是一個一個的點; 你平常能觸及的東西越多,點越多,才能構成一個知識的平面。

而社群的意義就在這,它幫你集結了在 iOS 各領域開發的人, 分享他們花了數個、或數十個晚上所得到的經驗,讓你了解其中的運作原理和設計想法。

產品和想法多數都是在互相碰撞的時候,產生而來的, 像是會使用 Firebase 的 real-time database, 和藍芽裝配的配對的話,那是不是能做一個即時的數據報告, 再加入類似 AWS 的 Cloud watch 的功能,送推播到另一個裝置幹嘛幹嘛(還沒想到XD)

對自己自學程式還沒有想法的人,不如先放下手機看看你周遭的生活, 你想透過手機 App 幫你解決什麼問題? 然而你便會找到方向,並找到一份適合你的工作,讓你接觸到更多 🙂

https://www.ptt.cc/bbs/MacDev/M.1493048535.A.E98.html

七天學會設計模式 – Singleton

最近和同事一起購入「七天學會設計模式」,不過書中是以 Java 作為示範語言;

而這邊,我會以 Swift 及 Objective-C 來攥寫範例並補充些內容。

Singleton

如同它的命名一般,在整個 App 運作時,僅會有一個 instance。

Swift

Swift 宣告 Singleton 的方式很簡單,就是在 class 底下宣告一個 static 的常數(constant)。

Objective-C

而 Objective-C 底下,我們要注意一些事情;

在 Multi-Thread 的情況下,我們得避免同時有多個 thread 執行建立 instance,故在創建時,必須使用 dispatch_once_t 來確保僅會有一個 thread 執行 instance = [[SingletonDemo alloc] init];

學會了如何創建 Singleton 之後,可以想想哪些物件適合以這種方式創建;

如「目前登入的使用者」,正是可以用 Singleton 的方式做設計,畢竟一個 App 同時僅能有一位使用者登入,是大多數軟體的設計,而這恰巧符合 Singleton 的精神。

Hello world! 哈囉!

歡迎來到 WordPress。這是你的第一篇文章。編輯或者刪除本篇文章,然後開始你的部落客生活!