寒哥教你學iOS – 經驗漫談

發表於2015-09-24
  • 本篇文章主要講解 4個問題
  1. load妙用
  2. aop面向切面程式設計
  3. NSNumber Or Int
  4. @()適配64位

1 讓appDelegate 減少負擔

經過漫長時間的學習 你終於掌握了iOS大法 你找到了份iOS開發的工作 信誓旦旦的要開始你的coding生涯 老闆對你非常器重 然後告訴你 我覺得你的技術 是非常刁的 那這個專案就你自己來搞吧 啊哦這就意味著這個專案你就從頭到尾處理 從軟體的架構 到頁面的展示 都交給你嘍

用著自己的半吊子水平 papapa的 coding 決心一定要把程式碼封裝好 寫的漂亮 (其實是聽大神說 封裝 其實自己不太懂)
專案到了尾聲 老闆告訴你我們的app 我們的app 將來得來個分享到朋友圈的功能吧 不然怎麼體現我產品的牛逼
然後你聽說友盟比較好使(有廣告的嫌疑) 你去友盟看了他們的文件 他告訴你你要在 appdelegate didFinishLaunch方法裡面寫了這個東西

 

過了幾天 老闆又說 我們需要統計下我頁面的資訊 你接入了友盟的統計 在appdelegate didFinishLaunch又 多了行程式碼

需求是無窮無盡 我需要bug統計(fir hud) 提醒使用者評分系統(iRate) 推送(jPush 信鴿 個推。。)
當初你決心一定要把程式碼封裝的完美 寫的漂亮的心早就被老闆的需求徹底打敗了
別擔心 寒哥教你小技巧

不知道你們用過 IQKeyBoardManageiRate這種智慧庫沒

大牛的readme 寫了這段話

Key Features
1) CODELESS, Zero Line Of Code 不需要寫任何程式碼

2) Works Automatically //自動工作

3) No More UIScrollView //不需要scrollview

4) No More Subclasses //不需要繼承父類

5) No More Manual Work //不需要配置

6) No More #imports //不需要匯入

其實不神奇 只是大牛用了 + load這個方法
學習OC都知道這個程式碼會在一個類被載入到執行庫中就會被自動呼叫 這不就實現了 自動呼叫

寫一個類繼承自NSObject

 

類似於定位也可以這樣寫

 
Paste_Image.png

模組和服務完全拆開

但是有的服務 如APNS需要LaunchOption 那就只能寫在appdDelegate 不過這樣的話已經摘除很多程式碼了 只剩下幾個固定的 到時候再修改appDelegate就會感覺非常清晰 了


2 ViewController繼承?

接著上面講 我們接入了友盟統計 友盟統計最基本的東西就是 統計頁面的pv

 
Paste_Image.png

友盟的這樣寫 對於新手的我們就覺得這不就so easy嗎
我開啟了某個vc(HomeViewController)
在程式碼裡面寫上了這句

然後我一個專案中可能有幾十個 甚至上百個頁面需要統計pv 我總不能每個節目都這樣寫吧

聰明的我們想到了繼承

MyBaseViewController:UIViewController
這樣就要做一件事 把我們專案中所有繼承自UIViewController的類全部改為繼承自MyBaseViewController 然而你真的覺得這樣好嗎 我們一個專案中有幾十個控制器 我就要把每個控制器改一遍

這種重複性的工作一是無聊 而是容易出錯 你複製著複製者就會遺漏掉某個類 重要的是 我們專案中很多類並不是直接繼承自UIViewController 有的可能是UITableViewController UICollectionViewContr0ller UINavigationController 甚至不常用的UISearchDisPlayController UIPopoverController UIPresentController 是不是突然覺得這麼多啊啊

這也不是坑的 坑的是將來你混成了大牛 招了個小弟 你告訴他你所有的類都要繼承自我寫的各種父類 新手總是會不經意見犯錯誤 有些類忘記繼承了 後期查起來難度非常大 浪費時間 所以這種設計是不合理的

  • 寒哥再次教你黑魔法 Method swizzling關於這個是幹嘛的 自行百度

這裡有一篇來自NSHipster博主的文章 英文
中文翻譯
還有一篇解釋runtime的文章傳送門
實踐

用方法交叉 我們就可以攔截吸引的方法了 上程式碼了
這樣就做到了面向切面程式設計(AOP)的思想

上程式碼

圖片程式碼一份 方便觀看

 
Paste_Image.png
 
Paste_Image.png

我們充分利用了黑魔法達到了面向切面程式設計的好處

思想來源這裡http://casatwy.com/iosying-yong-jia-gou-tan-viewceng-de-zu-zhi-he-diao-yong-fang-an.html

黑魔法非毒藥 遵守一個規範寫出來的程式碼是不會Crash的 只要能幫我們解決問題就是好東西
黑魔法效能 有瓶頸? 都到runtime的底層了 你還擔心有瓶頸 少年安心使用就好了 不服 可以用Time Profiel測試
黑魔法也非萬能 像 我們在導航控制器要封裝手勢 統一管理左側返回按鈕 這些東西 還是繼承來得好

技術就是工具 黑貓,白貓,抓住老鼠就是好貓



3 網路訪問引數到底用基本資料型別還是物件

下面看兩個方法

 
Paste_Image.png

在訪問網路請求時 對於有引數的請求 設計一個方法 主流為以上兩種

  1. 使用物件當做引數
  2. 使用基本資料型別做引數

一般情況下 這並沒有什麼大的區別 但是寒哥給出的意見是Never出現基本資料型別

一般情況下 開發者可能覺得並沒有什麼區別 下面我給大家舉個例子

在設計一個分頁展示資料的時候: 在頁面上的邏輯就是 預設載入第一頁 每頁長度為10 (Server端的同學一般都很友好 預設情況下 不傳每頁的長度就是10個) 但是傳了就會覆蓋掉後臺寫的預設引數 如傳了20 Server就吐20條資料

  1. 在第一中設計方案中: 可能在某個控制器中保留一個PageNo PageSize 的物件的成員變數 ,在下拉重新整理或者上拉載入的時候 會傳遞對應的引數給請求方法 , 如果沒有特殊需求的話pageSize 物件可有可無 也就是有可能為nil ,那在對應的param可能就沒有這個引數傳遞給Server 。
    Server 就會交還給我們某頁的20條資料
  2. 在 第二種設計方案中 : 可能也在某個控制器中保留一個PageNo pageSize的基本資料型別的成員變數, 在訪問網路請求時交給對應的方法 , 一般沒有特殊需求我們也不會對PageSize專門設值 但是 基本資料型別在OC 和C語言這種傳統的程式語言中是有預設值的 為0,雖然我們沒有給pageSize 賦值 但是預設系統預設給了0這個初始值 那麼傳遞到Server的時候 就會覆蓋掉Server 寫的預設pageSize=10 這樣的請求既不會報錯 也不會返回資料
    超級難除錯

所以在網路訪問中 寒哥給出的意見就是Never出現基本資料型別


4 用NSNumber比基本資料型別的好處 ? 64位適配問題

我們一般都用來當做網路請求的引數 快取或者展示到頁面

  1. 對於網路請求的引數 因為NSDictionary只能放物件 所以NSNumber最好的方式
  2. 快取 無論快取到plist 還是KeyArchive 都是需要物件的所以NSNumber也非常合適
    3 展示到頁面
    我見過這樣給頁面上賦值的朋友
 
Paste_Image.png

我們看到這樣貌似並沒有什麼不妥
但是我們把裝置切換到iPhone5S以下 也就是32位的裝置

 
Paste_Image.png

注意這裡有Warning
為什麼呢 我們來看下NSInteger的標頭檔案

 
Paste_Image.png

在32下裝置是Int 在64位是long
我們都知道蘋果不允許不支援64位的app上架 但是貌似我們從來沒有為32位和64位做適配

其實不然 在printf 和NSLog 時 對應%d %zd %f 佔位符是非常嚴格的 如果不對專案就會造成意外的結果

 
Paste_Image.png
 
Paste_Image.png

其實拿到一個NSNumber我們並不知道他到底是int long unsigned int Bool 直接針對某個型別轉換是有風險的 但是其實Clang 給我們提供了個非常好用的Macro @()

Paste_Image.png

NSNumber並不是一個簡單的類 它是cocoa 中 類簇的實現參考資料

相關文章