你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS開發者如何提高自己的水平?

iOS開發者如何提高自己的水平?

編輯:IOS開發基礎

(原文:Leveling Up 作者:Mark Dalrymple 譯者:xiaoying )

levelUp.jpg

不知道你有沒有參與或是旁觀過iOS開發的黑客馬拉松,我覺得這是非常好的事情,在這裡人們幾乎不睡覺,一起腦洞大開,在Objective-C運行時環境下,利用iOS的相關知識攻城略地,度過激情四射的72個小時。對於我來說,它們讓人心潮澎湃,我的所有平台知識都在頭腦風暴下接受考驗,我的技能也得到錘煉。

在某場活動裡有一次我和我們組的一個伙伴在聊天的時候,他問我:“MarkD,我要怎麼樣才能學到所有那些知識的細節?我覺得我現在有點迷茫,我的編程工作好像就是使用tableview和一些其他有的沒的。”這是個讓人不敢輕易回答的問題,尤其當這個問題是從一個經驗豐富的工程師口裡問出來的時候,像“呃,你只要不斷地去實踐就好了”這種答案肯定是不負責任的。

他的問題讓我不禁聯想到,到現在為止,我已經專職編程(其實也是為了生計)23年了,這著實很嚇人,因為這個時間比我的一個同事的年齡都大——你們這些小屁孩快離開我的領地啦,開玩笑的,呵呵。不過,經過這麼些年裡的學習和探索,我也確實得到了很多很寶貴的東西。當然,每個人的想法可能都是不同的,但這裡是我對於他的問題的回答。

閱讀

大量的閱讀,把大量的信息塞進腦子裡。現在外界有大量的書和博客可以閱讀,尤其是和過去相比,那時所有關於Mac編程的書加起來估計也塞不滿書架上的一層。現在我最喜歡的書是Rob Napier和Mugunth Kumar的《iOS 6: Pushing The Limits》。此外我還要必須推薦下《Advanced Mac OS X Programming : The Big Nerd Ranch Guide 》,因為這本書深入到了很多OS X系統底層的細節,這些細節很多也都是同時適用於iOS的。當然,也不能忘了Amit Singh的巨著《OS X Internals book》(如果你將這本書的電子版裝進自己的Kindle,你的Kindle也會變得重很多^_^),這本書裡的有些部分有點過時了,但在這本書裡能看到很多一個真實操作系統內核的實現細節,這還是挺吸引人的。

我們接觸到的網絡世界也有很多信息值得閱讀。除了當前你在閱讀的這個不起眼的網絡博客,你還應該讀一下Mike Ash的NSBlog博客。同時我也經常去NSHipster和Jeremy W.Sherman 的博客。

另外,也別忘了去讀一下官方文檔,在Xcode裡浏覽一下Cocoa或者UIKit的文檔。我在我的iPad上裝了一個DocSets,這樣我就能利用等待事情時候的間隙去閱讀一些東西。不要把自己限制在一個你一直處在的圈圈裡,如果你整天都在使用NSTableView,可以抽時間看看IOService,也許你永遠也用不到它,但是你也許會發現一些能啟發你未來學習的課題。

我會嘗試定期的閱讀編譯器和調試器的文檔。gdb的文檔很完整,而且它現在仍然是和iOS編程息息相關的——因為lldb在設備上用還是有些不可靠。LLDB的網站也有很多支持文檔,所以可以去看一下它內建的幫助系統去學習所有可用的命令。閱讀所有可閱讀的東西,如果你看到一個很難看懂的功能特性,可以嘗試去搞懂它存在的價值。

關於編譯器的內幕知識可以在這裡找到,同時不要忘記看一下頭文件的相關知識,那裡也有很多有用的信息。

當然,我不可能全部記住所有的知識,實際上我已經忘記了大部分我看過的東西,但是我時常會碰到這樣的時刻,“我想我之前一定在什麼地方看到過與這個相關的信息,那麼是在哪裡看到的呢”或者忽然想到“哦,對了,Jeremy曾經寫過一篇博客,裡邊他用12行代碼實現了Cocoa的所有功能,而且他有一個很好的高階消息處理類別(category),我可能能用到。”

分析

為了學習事物的工作原理,我喜歡首先去了解它們互相之間的調用關系,這往往能讓人得到一些啟發。比如在本篇文章描述的這個問題裡,解決問題的關鍵是搞清楚“究竟是誰創建了NSUndoManagers的實例”。或者,為了了解MPMusicPlayerController到底是怎麼切換歌曲的,你可以通過持續觀察在你的應用裡不斷被發送出來的notification來分析其中的工作原理 。

同時,有很多很強大的工具可以用來幫助你監聽並分析你的程序和庫。你可能不會每天都用到它們,可能有些工具一個月甚至三個月才能用到一次,但是把它們放在手邊會對你很有幫助的。下邊是一些相關的工具介紹:

源文件:clang和lldb的源文件都是很容易得到的,那麼你可以把他們下載下來並且編譯通過。當你對這個語言的某個地方的工作原理不清楚時,就可以打開源文件找找看。你也可以在http://www.opensource.apple.com得到一份相當不錯的Core Foundation框架的源文件(和其他一大堆東西在放一起),其中我覺得真正有意思的是這麼幾部分:“xnu”——內核,“cf”——Core Foundation,還有“objc”——Objective-C運行時環境。另外,一定要去仔細看看Cocoa的頭文件,裡邊可能會有很多你不是很了解的東西,像NSAserrt, 然後搞懂它們。

編譯器:你可以在任何可見的符號處設置斷點,不論是是你自己寫的代碼行裡,或者在二進制的庫裡的函數和方法處。你可以直接在Xcode裡添加一個符號斷點,下圖是我在UIApplication裡的私有方法_performMemoryWarning上面設置的一個符號斷點。

perform-memory-warning.png

你也可以在模擬器裡出發一次內存警告,來看看它是怎麼被處理的:

memory-warning-stack.png

Notification監視:Notification常常用來對代碼進行解耦,當一些事件發生時,我們可以發送一個notification通知另外一個對象去完成其它動作。NSNotificationCenter和與之相關的一些方法太有用了,幾乎所有的事情都會用到它,如果想對所有系統中發出的notification進行監視,你可以添加一個notification監視器。

DTrace:我知道很多人都希望我不要再談論DTrace了,哈哈,但是沒有它我怎麼才能找到諸如_performMemoryWarning這種符號?很顯然,你不可能在任何蘋果的官方文檔找到這個方法,因為所有帶有前導下劃線的方法都是你不能訪問的“私有API”。這裡有一個DTrace的使用實例,在Clash of the Coders中我也想回答另外一些問題,比如“UITouche是在那裡被創建和分發的?”,還有“當加載一個nib文件時,到底是什麼東西在文件系統定位到了這個文件?”。這也促使我寫了一個工具腳本,spy.d(可以在這裡找到)。

spy.d是一個簡單的腳本,它利用objc provider來跟蹤Objective-C消息傳輸,同時可以有一個列表來制定跳過的消息類型,然後還可以指定一個“非常感興趣的”消息列表,對它們的全部堆棧進行跟蹤。我運行了spy.d然後在模擬器裡觸發一次內存警告,得到以下信息:

# ./spy.d  61271
...
UIApplication -didReceiveMemoryWarning
NSNotificationCenter +defaultCenter
NSNotificationCenter -postNotificationName:object:
...
UIImage(UIImageInternal) +_flushCache:
UIViewController +_traverseViewControllerHierarchyWithDelayedRelease:
UIViewController -didReceiveMemoryWarning
UIViewController -_traverseViewControllerHierarchyFromLevel:withBlock:
RMScheduleVC -didReceiveMemoryWarning

這裡可以看到,UIApplication得到這個內存警告,然後它發送了一個notification,作為響應,UIImage清掉了它的緩存,之後,UIViewController的類方法按照層級遍歷它的控制器,告訴它們它收到了一個內存警告,然後它傳送到了我的RMScheduleVC代碼裡。

class-dump:Objective-C的運行時環境包含了很豐富的元數據,這些元數據使得你可以在運行時查看類和方法,也能找一些其他的好工具來操作他們。這些元數據(和目標文件,還有庫)實際上是存儲在程序的可執行文件裡的,它們是可以被導出的,Steve Nygard的class-dump 可以提取出這些元數據然後對於所有的類生成它們的接口。例如,這是從UIApplication得到的信息:

...
- (void)_purgeSharedInstances;
- (void)setReceivesMemoryWarnings:(BOOL)arg1;
- (void)_receivedMemoryNotification;
- (void)didReceiveMemoryWarning;
- (void)_performMemoryWarning;
- (BOOL)_isHandlingMemoryWarning;
- (void)_processScriptEvent:(struct __GSEvent *)arg1;
- (void)_dumpScreenContents:(struct __GSEvent *)arg1;
- (void)_dumpUIHierarchy:(struct __GSEvent *)arg1;
- (void)setSystemVolumeHUDEnabled:(BOOL)arg1;
...

這裡有太多的非常有趣的東西,你可以在這些地方增加斷點,或者查看堆棧信息,甚至可以更進一步看到這個類的實現。

Hopper Disassembler: 這是一個讀取目標代碼並且顯示相應的匯編代碼的工具。下面是用它來查看UIKit中UIApplication類的_performMemoryWarning方法的實現。

memory-warning-disassembly.png

Hopper的厲害之處在於,它可以將匯編代碼轉換成偽語言,這樣開發者可以更好的看到代碼流程。

memory-warning-pseudocode.png

同時,這也是一個學習匯編語言的好機會。你今後很可能會需要讀很多編譯器生成的匯編代碼,尤其是當編譯器對代碼做過優化時,匯編代碼會更不容易看懂。

Instruments: Instruments不僅可以用來處理性能問題,它也可以用來在這個程序的所有代碼裡尋址,不論是你自己寫的代碼還是庫裡的代碼,用它和其他工具一起,你就可以攻擊別人的程序了。比如如果你想搞清楚UISlider(滑塊控件)是怎麼來做實時跟蹤的,在一個包含滑塊控件的應用裡打開Instruments,拖動滑塊來回移動大約10秒鐘,然後查看在Instruments的調用堆棧的最上層是什麼,你還可以在模擬器裡使用DTrace,或者進行反匯編,看看會發生什麼。

小小的提醒:當你想要把自己從這些工具中學到的知識應用到你的程序中去時,一定要小心。這些工具對於調試程序和理解程序工作原理很有幫助,但是裡邊會有很多是依賴系統實現細節的或者是一些私有權限的API,如果把這些東西應用到你要發布的應用程序中去的話,很可能會使你的程序變得很脆弱,或者不被新版本的系統支持。如果你的程序是給那些付費用戶使用的,或者用戶會使用你的程序做一些很重要的事情,那麼可能會造成一些不好的後果,這樣就不專業了,努力去做一個專業的開發者。

實驗

現在你有了一套工具,是時候該去真正地學些東西了,我覺得最好的學習方法就是去真正的實踐,不斷地去犯錯誤!你想深度地學習UITableView?那麼就去寫大量的關於表視圖的代碼。多看文檔,去閱讀那些你可能還沒用到過的一些API的頭文件,寫代碼去使用它們。讀一些博客,用class-dump去測試它們,從結果中找到那些有趣的私有API,看看你是否能用普通的接口去觸發它們。用DTrace測試它們,看一下消息的流向。把notification監視器放進去,看看你能得到什麼信息。如果實驗的時候出現了問題,就用你平常使用的調試方法去搞清楚問題出在哪裡,也可以試著自己寫代碼去重新實現它的功能。

我自己喜歡在UIKit/AppKit的代碼世界裡四處玩耍,所以我寫了大量的小程序去實現這兩個框架裡的數據結構和一些語言特性。Steve Sparks是在參加Clash of the Coders時我的隊友,他也有他很多自己的愛好,隨便在Xcode裡創建一個工程,拖進去一個標簽試圖(tab view)和導航控制器(navigation controller),他就能搞出一個新實驗來。如果你想要玩一玩UIScrollView,那麼把它拉到一個新的視圖控制器(view controller)裡,連接到工程裡去,你就可以在模擬器或者真實設備上運行了,記得在工程加入代碼版本控制,你就可以輕易的記錄下來你做過的所有實驗。

同化

到現在為止,你確定了要學習的東西,寫了一堆的代碼,它們也都調試通過了,可能你還記了很多筆記,那麼現在是時候消化一下,把它們都同化為自己知識體系的一部分了,現在你可以好好睡一覺,去騎會兒自行車,或者洗個澡,放松下來。然後把這些知識在腦海裡歸類,看看能否得到一些抽象的概念,然後把它們用到其他的類裡。現在的軟件開發有時就像機械化裝配——有一堆的功能要去實現,還要把很多類組裝在一起。

這個同化知識的過程是很有趣的,因為你的大腦開始建立一些概念間的關系。這裡我講到的很多例子都是來源於在Clash of the Coders上編程時碰到的一個簡單的問題:“我們想要手動地去觸發內存警告”,來調試內存和緩存方面的問題。整個研究過程大致是這樣的:

  • 我們在模擬器裡觸發內存警告

  • 使用notification監視器查看是否有notification被發出,為什麼會有notification發出呢,我們可以接收並且對這些notification進行反饋。

  • 這個notification並沒有觸發別的任何行為,該死,我在想這是為什麼。

  • 內存警告觸發時,什麼方法被觸發了呢?用spy.d來查看到底發生了什麼,哦,看,_performMemoryWarning看起來很有意思嘛。

  • 是否還有其他的內存警告方法我應該去看一下的?拉出來class-dump看看裡邊有什麼。

  • 發送_performMemoryWarning消息給UIApplication對象好像沒有觸發內存警告,怎麼回事,為什麼沒有發出notification呢?

  • 好吧,好奇害死貓,我又用Hopper看下它到底做了什麼。哦,原來如此,那裡有一個視圖控制器樹和SQLite的東西,如果僅僅只有內存警告的notification被發出,它們是不會被執行的。

  • 最後我在調試控制台裡加入了一個觸發內存警告的按鈕,同時為了不讓它最終顯示出來,用#if塊把它保護起來。

總結

差不多以下就是我用來磨練自己技藝的奧義:

  • 閱讀。 把一大堆的知識塞進腦子裡。隨著時間流逝,終歸有一些會留在腦海裡。我覺得有些東西讀起來還挺有意思,那麼也能算作一種愉快的消遣。

  • 分析。 多去熟悉並了解一些工具,從高層的到底層的,不要害怕去使用他們,也不要害怕用各種各樣古怪的方法使用他們。例如DTrace就像一把大錘子,有時你可以用它把一個bug分解成很多小片段。使用這些工具去深度挖掘軟件背後的原理和其運作方法。但是請保證你不會用這些知識來作惡。

  • 實驗。 一定要寫代碼,寫大量的代碼。另外通過做實驗去接觸新發現的編程方法,並且不斷地梳理這些知識。

  • 同化。對於學到的知識,不斷的進行反省,洗滌,過濾,重復,讓他們真正成為自己知識體系的一部分。然後在接下來的20年裡持續的去這麼做。學習更加高深的知識是一個長期的過程。

(本文為CocoaChina組織翻譯,本譯文權利歸譯者所有,未經允許禁止轉載。)

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved