前言.
1.Xcode IDE概覽

說明: 從左到右,依次是“導航窗格(Navigator)->邊列(Gutter)->焦點列(Ribbon)->代碼編輯窗口(Standard/Primary Editor)”。 邊列(Gutter):顯示行號和斷點。(上圖未顯示,可通過command + , 找到 Text Editing ->使 Line Numbers 選中 ) 焦點列(Ribbon):灰色深度與代碼嵌套深度相關:鼠標懸停可突出顯示右側相應代碼塊(Focus code blocks on hover),鼠標單擊可折疊右側相應代碼塊(Code folding)。
2.偏好設置(command + ,)

通過“command+,”快捷鍵或”Xcode|Preferences”菜單呼出偏好設置。
(1)一般設置(Preferences->general 這里我們一般不需要更改什么設置)
* Show live issues:這個是表示在你編輯代碼的時候,是否實時分析你寫的代碼,並實時的報告錯誤。一般選中。
* Continue build after error:continue building after errors出現錯誤后仍然繼續編譯,默認情況下,發生錯誤后,會停止編譯。
* locked files:默認情況下,Xcode會鎖定用戶正在編輯的文件,防止被其他工具修改,勾選后,會允許其他工具修改。
* find navigator detail:搜索導航器細節,可以選擇搜索到的項目可以占據多少行的顯示空間。
* issue navigator detail:問題導航器細節,可以選擇當前問題占據多少行的顯示空間。
* dialog warnings:對話框警告,重置不要再詢問我,讓其再次彈出警告。
(2) Accounts賬戶(Preferences->Accounts 用來管理蘋果開發者賬號以及Git相關的賬戶信息。)
點擊+號,會出現添加賬戶,添加資源倉庫,添加服務器三個選項。
* 添加賬戶,可以添加開發者賬號。
* 添加資源倉庫,輸入資源倉庫的地址,再輸入相關配置即可加入新的資源倉庫(可參考:https://www.cnblogs.com/china-fanny/p/5943589.html)。
* 添加服務器,選擇本機MAC上搭建的服務器,即可完成添加。
(3)表現行為(Preferences->behaviors 這里我們更不需要更改什么)

選項卡分為7部分,分別包括了編譯、測試、運行、CUP幀捕獲、搜索、自動集成、文件部分。
每個部分有各種階段,包括開始、發現問題、成功、失敗等階段。對於每一階段,我可以依次進行相關行為配置:
* play sound:階段完成時播放聲音
* speak announcement using:使用系統自帶的聲音為開發者播報當前程序處於何種階段
* notify using bezel or system notifacation:使用系統通知或者提醒卡來通知
* bounce Xcode icon in dock if application inactive:如果應用處於未激活狀態,在dock中跳動
show...:6個選項,分別設定xcode執行到該階段時,要顯示還是隱藏那些導航欄,那些窗口等
* navigate to:執行到該階段時,跳轉到第一條發現的問題還是當前日志
* run:執行到該階段,執行選項所設定的apple script腳本
(4)Navigation導航(Preferences->Navigation)
* activation:當打開某個標簽頁或者窗口時,讓其保持活動狀態。
* navigation:選擇在使用導航區域的時候,是用的主編輯器primary還是輔助編focused輯器來打開新的導航文件
* optional navigation:當使用optional鍵來進行導航的時候,是使用同一個助理編輯器打開,還是使用另一個助理編輯器打開,或者另一個標簽頁或另一個窗口。
* double click navigation:雙擊導航時,使用另一個標簽打開還是另一個窗口打開,或者讓其和單擊的操作相同。
(5)主題及字體(Preferences->Fonts & Colors)
* 選中一種主題(theme),例如“Midnight”,推薦使用Monokai、Ciapre。
* 將 `*.dvtcolortheme` 文件拷貝到 `~/Library/Developer/Xcode/UserData/FontAndColorThemes/`即可安裝主題, 重啟 Xcode 即可選用。
* Xcode默認字體為menlo,也可選擇 Consolas、Monaco、Consolas、Droid Sans Mono、Source Code Pro、Bitstream Vera Sans 等其他等寬字體。
* shift 選擇主題 Source Editor/Console 中的所有項,點擊 Fonts 可更改字體(大小)。
(6)編輯器配置(Preferences->Text Editing 分為editing編輯和indentation縮進兩部分)
編輯部分(editing):
* line numbers:是否顯示行號
* code folding ribbon:是否顯示代碼折疊帶。代碼級別相同的代碼段,左側會有一個灰度不同的色帶顯示,灰度相同,表示同一個級別。
* focus code blocks on hover:是否懸停是聚焦代碼塊。鼠標懸停時,會有一個矩形邊框來聚焦代碼所在類別。
* page guide at column:頁面的最大行長,設定一行最多有多少個字符,如果超出行長,會自動換行
* highlight instances of selected symbol:高亮選中的符號,高亮顯示的符號是一條虛線顯示的,delay表示高亮效果多久會顯示出來。
* suggest completions while typing:輸入時顯示代碼提示
* use escape key to show completion suggestions:使用esc來顯示代碼提示
* automatically insert closing braces:自動插入結束符
* enable type-over completions:啟動結束符自動完成,即輸入{后,自動補齊后面的}
* automatically trim trailing whitespace:自動刪除代碼兩側的空格
* show iteration counts:顯示迭代計算
縮進部分(indentation):
* Prefer indent using:Spaces(為保持一致的視覺呈現和行末注釋對齊,建議使用空格)
* Tab width:4 spaces(tab expand,1個tab=4個空格)可以設置tab和縮進的空格數目。
* line wrapping:換行,可以設置是否允許換行,允許的話,還可以設置換行之后行的縮進字符長度
* syntax-aware indenting:語法換行,根據語法來自動決定換行的行為
* automatic indent for:自動縮進,設定哪些符號可以自動執行自動縮進功能
* Indent width:4 spaces(自動縮進步長=4個空格)
(7)跳轉打開方式(Preferences->Navigation) * Activation:When a tab or window opens,make it active。
當新建窗口或標簽時,立即激活聚焦。 * Navigation:Uses Primary/Focused Editor。
打開Project Navigator中指定的文件時,在主編輯器窗口/當前聚焦窗口打開,建議選擇Focused。 * Optional Navigation:Uses Single Assistant Editor。
打開Project Navigator中指定的文件或跳轉到符號定義所在文件(command+單擊)時,若按下option鍵,則在輔助窗口打開。 * Double Click Navigation:Uses Separate Tab。
雙擊打開Project Navigator中指定的文件或跳轉到符號定義所在文件(command+雙擊)時,新建標簽頁。 (6)SCM(Preferences->Source Control) * Enable Source Control:啟用/禁用Xcode自帶Source Control Manager(SCM)。 * Comparison View:Show local revision in [Right] Side。
打開version editor比較窗口時,左側顯示服務器基線版本(base),[右側]顯示本地修改過的工作拷貝(local working copy)。
* refresh local status automatically:自動刷新本地狀態,決定是否自動更新
* refresh server status automatically:自動刷新遠程服務器狀態,決定遠程代碼源中代碼是否會自動保存
* add and remove files automatically:自動添加和移除文件,當遠程代碼庫更新后,自動添加和移除本地項目所沒有的文件
* show local revision on ... side:在...側顯示本地版本,決定本地版本在哪一側。
(7)SDK/Simulator(Preferences->Downloads)
* Downloads:可下載Components(SDK&Simulator)和Documentation。
(8)構建輸出目錄(Preferences->Locations->Locations)
* 當選擇為Default時,Derived Data的目錄為~/Library/Developer/Xcode/DerivedData。
* 當選擇為Relative時,Derived Data的目錄為當前*.xcodeproj所在的目錄。
* 當選擇為Custom時,Derived Data的目錄需自定義。
* 不建議使用絕對路徑,因為寫死之后,換環境或換平台,又要重新修改路徑,且同名project target的build folder會覆蓋,建議使用相對路徑(Relative)
3.代碼閱讀
(1)Help
* option+點按:查看選中符號的幫助提示(Quick Help for Selected Item)。
(2)View Navigator
* command+0:Show/Hide left tool panel(Navigator Area)
* command+1-8:Project/SourceTree/Symbol/Find/Issue/Test/Debug/Breakpoint/Report Navigator
* option+command+0:Show/Hide right tool panel(Utility Area)
* option+command+1/2:show the file/quick help inspector
可按下command+0隱藏左側欄Navigator,再按下option+command+0隱藏右側欄Utility,只顯示Standard/Primary Editor,聚焦有效利用屏幕進行編碼。
(3)View Editor Organization
* control+1:Show Related Items(例如Superclasses/Subclasses、Callers/Callees、Protocol Implementor/Implemented、Includes/Included By)。可輸入實時搜索匹配。
* control+2/3:Show Previous/Next History。可輸入實時搜索匹配。
* control+4:Show Top Level Items。
* control+5:Show Group Files(當前文件夾內的所有文件)。可輸入實時搜索匹配。
* control+6:Show Document Items(當前文件的Symbols)。可輸入實時搜索匹配。
(4)Eidtor Window/Tab Switch
* command+shift+[/]:切換標簽頁單/雙指左右滑動
*(control+command+←/→):在單標簽頁打開的多個文件間切換(Go Back/Forward)
(5)Symbol Jump
* command+L:跳轉到指定行。
* shift+command+O:Open Quickly,快速全局查找文件、符號,非常常用!
* command+點擊Editor中選中的符號:跳轉到符號定義(jump to definition)。
* control+command+J:跳轉到指定符號的定義處或實現處(Go to Declaration/Definition)。
有時工程正在Loading、Indexing或Processing files時,“command+點擊”無法響應,此時可試試control+command+J。
* control+command+↑/↓:切換頭文件/實現文件
在Project Navigator中選中文件右鍵或通過菜單“File->Show in Finder”:在Finder中定位該文件。
(6)Symbol Navigator
* command+2可聚焦左側導航欄中的符號導航器。
* filter0:底部編輯框輸入符號(show symbols with matching name)= filter1 result+filter3 result
* filter1:show only class and protocol symbols (hide other global symbol types),包括project和system層次。
* filter2:show only project-defined symbols,過濾顯示當前工程中的符號。filter2的結果是filter1的子集,較常用。
* filter3:show only containers(hide members),過濾顯示包含該單詞的符號。
注意:* control+6只列出當前代碼所在interface的符號,而Symbol Navigator是當前工程(Project Scope)的所有符號列表的Hierarchy,符號種類包括Classes/Protocols/Functions/Structs/Unions/Enums/Types/Globals。
* 編輯器中光標所在符號處,Navigate菜單或右鍵快捷菜單可[Reveal in Symbol Navigator],在符號導航器中定位當前符號,亦可查看當前符號所屬類的層次。
(7)Code Folding
* option+command+←/→:折疊當前代碼塊,包括@interface …@end、@implementation …@end
* option+shift+command+←/→:折疊該文件內所有代碼塊(方法/函數:{ Methods&Functions })
* control+shift+command+←/→:折疊當前注釋塊(/*Comment Blocks*/)
(8)Focus Switch
* (shift+)option+command+`:MoveFocus to (Previous)Next Area.
* command+J:焦點切換(Move Focus),可配合鼠標和方向鍵。帶‘+’的“Move focus to a new assistant editor”可以快速在輔助編輯窗口中打開頭文件(*.h)/實現文件(*.m,*.mm)。
* shift+command+J:在項目導航中定位當前編輯其中打開的文件(Reveal in Project Navigator)。
4.代碼編輯
(1)File | New
* control+command+N:File | New | Workspace
* shift+command+N:File | New | Project
(2)Text Editing
* command+X/C/V:剪切/復制/粘貼
* command+Z(+shift):撤銷(重做)/Undo(Redo)
* command+[/]:向前/向后縮進(Shift Left/Right)
* option+command+[/]:將當前光標所在行代碼上移/下移一行(Move Line Up/Down)
* command+/:以雙斜杠(//)注釋選中的代碼,再此按下可取消
* Parentheses/Brackets/Braces Matching:雙擊某個分隔符(如()、[]、{} 等),Xcode會選中匹配代碼塊。
* Editor→Structure→Balance Delimiter:根據當前光標代碼所在位置,自動向外擴展選擇外層代碼塊。
(3)Auto Completion
* esc(control+.)就當前輸入上下文呼出/隱藏智能提示列表(Auto
* Completion List);
上下方向鍵(↑/↓)在智能提示列表中選擇選項。當然,也可以用control+.;
enter選中列表中備選的消息符號;
tab在輸入符號不完整時可一截一截匹配;選中消息符號后,tab可在各個參數占位符之間移動,enter可選中參數占位符先臨時補位填充。
輸入Objective-C對象及消息名,然后輸入 ],自動補充對象名左側的[,完成中綴符(infixnatation)包圍。
(4)Find菜單(control+單擊)
* 當鼠標定位或選中某個符號時,可呼叫右鍵快捷菜單:
* Find Selected Text in Workspace:在當前工作空間查找選中文本或光標所在行的OC冒號分割方法名。
* Find Selected Symbol in Workspace:在當前工作空間查找選中文本符號或光標所在行的OC冒號分割方法符號。
* Find Call Hierarchy:查找選中文本符號或光標所在行的OC冒號分割方法符號的調用着(Callers)。
對應Find菜單中有Find Selected Text in Project、
Find Selected Symbol in Project(control+shift+command+F)、
Find Call Hierarchy(control+shift+command+H)。
說明:Find Call Hierarchy等效於control+1|Callers。
(5)Find & Replace
* command+F:當前文件查找。
* shift+command+F(command+3):在Find Navigator中全局查找。
可在[Preferences-General]中設置Find Navigator Detail的顯示行數(當Navigator Area較窄擠壓時)。
* Find:可指定查找內容(Text/References/Definitions/Regular Expression);
* 放大鏡:下拉可查看最近查找歷史;
* In Project:查找范圍(可指定Group);
* Text:匹配規則(可指定Containing,Matching,Starting with,Ending with);
* Case:是否區分大小寫(可指定 Matching/Ignoring)。
* 對於查找出來的結果可以delete刪除非預期干擾結果條目,也可以多擇或全選Find Results拷貝出來整理分析。
* option+command+F:當前文件替換。
* option+shift+command+F:在Find Navigator中全局替換。
* Replace:逐個替換;
* All:所有替換;
* Done:替換完成。
6)Copy Symbol 例如,光標停留在NSMutableArray的insertObject:atIndex的前半截單詞insertObject上時:

有三種復制方式: * command+C:Copy(光標所在位置的單詞):insertObject * control+shift+command+C:Copy Symbol Name(光標所在位置的消息符號名稱):-insertObject:atIndex: * option+control+shift+command+C:Copy Qualified Symbol Name(光標所在位置的消息符號全名,帶所屬類名):
-[NSMutableArray insertObject:atIndex:] 通過后兩種快捷方式,可以便捷地復制Objective-C特殊的冒號分隔的消息符號名稱。
(7)Open with External Editor——SublimeText
<1>在左側導航欄(Project Navigator)中選中某個文件右鍵快捷菜單中有【Open with External Editor】,默認呼叫Mac OS X自帶的文本編輯器(TextEdit)打開。我們可以按照以下步驟設置快捷鍵:
【系統偏好設置(System Preferences)->鍵盤(Keyboard)->快捷鍵(Shortcuts)->應用快捷鍵(App Shortcuts)】,
點擊+號,選擇應用程序【Xcode.app】
准確填寫[菜單標題],即菜單命令名稱【Open with External Editor】,聚焦[鍵盤快捷鍵]編輯框時,同時按下想要設置的組合鍵即可,例如option+command+O(⌥⌘O)。
可針對Xcode工程代碼文件(*.h/*.hh/*.c/*.cc/*.m/*.mm)設置默認打開程序為Sublime Text.app:右鍵Get Info(command+I),Open With選擇Sublime Text.app並 且Change All。然后,Xcode|Open with External Editor將在Sublime Text打開選中文件。
<2>另外,可下載安裝OpenInSublimeText插件,支持呼叫SublimeText打開Xcode當前正在編輯的文件。
從github下載打開OpenInSublimeText.xcodeproj工程進行編譯(command+B),生成的插件OpenInSublimeText.xcplugin將被集成到Xcode插件目錄
(~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins)下。
重啟Xcode將警告提示Unexpected code bundle "OpenInSublimeText.xcplugin",忽略警告選擇[Load Bundle]即可。
Xcode Editor菜單中將新增[Open In Sublime Text]項,可設置其快捷鍵位為shift+command+S(⇧⌘S)。

5.輔助編輯(Assistant Editor)
1)打開/關閉輔助編輯窗口
Assistant Editor有點類似VC中的Code Definition Window,可實現分屏查看代碼Counterpart,方便交叉參考代碼編輯。
option+command+enter/,:打開Assistant Editor。
command+enter:關閉Assistant Editor。
可通過菜單[View|Assistant Editor]設置Assistant Editors的方向,例如On Right。
(2)呼叫輔助編輯窗口(option+)
在Mac OS X日常操作中,我們已經認識到option這把單刀雙擲開關的妙用:按住鼠標移動或三指觸控移動時,按下option鍵可實現豎直塊選;調節音量/亮度時,按住option+shift 可以四分之一單位微調。
使用Xcode快捷鍵進行切換或跳轉動作時,若同時按下option可以在輔助編輯窗口中打開相應文件或符號(For optional navigation (Option-clicking or Option-choosing a file), opens the file in a new Assistant editor pane.)。若在輔助窗口中操作,則在主窗口(Standard Editor)中打開。
option+點擊Project Navigator中選中的文件:在輔助編輯窗口中打開選中文件。
option+command+點擊Editor中選中的符號:在輔助編輯窗口中打開符號定義(jump to definition in assistant editor)。
option+control+command+↑/↓:在輔助窗口中打開對應的頭文件(*.h)/實現文件(*.m,*.mm,*.cc)。
點擊查看shift+command+O、shift+command+F(command+3)選中的文件或符號時,可同時按下option在輔助編輯窗口中打開。
在control+1~6中打開選擇結果時,均可同時按下option在輔助編輯窗口中打開。
(3)導航窗格(option+shift+)
在Xcode以上種種切換跳轉操作時,按下option的同時按下shift,通常會呼出一個導航窗格(option+command+<),可選擇在new window/tab/assistant-editor打開顯示。
6.環境變量(Build Setting Macros)
1)查看環境變量宏
命令行進入HelloWorld工程目錄,執行xcodebuild命令並帶上“-showBuildSettings”參數:
$ xcodebuild -project HelloWorld.xcodeproj -target HelloWorld -configuration Debug -showBuildSettings > xcodebuild_showBuildSettings.txt
則xcodebuild_showBuildSettings.txt中保存了Build settings for action build and target "HelloWorld”,其中dump了所有的環境變量。
(2)Xcode5(Mac OS X 10.9)的部分環境變量
約定1:~=當前賬戶的HOME目錄,例如“/Users/faner”。
約定2:build構建基礎路徑:BUILD_PATH = ~/Library/Developer/Xcode/DerivedData/Build。可通過“File->Project Settings”查看Derived Data Location。
約定3:環境變量宏(Build Setting Macros)引用格式:${MACRO},同Build Phases Run Script中的語法。
下面是摘選自xcodebuild_showBuildSettings.txt的部分常用環境變量。
(a) ARCH & PLATFORM & SDK
ARCHS = i386
CURRENT_ARCH = i386
PLATFORM_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform
PLATFORM_NAME = macosx
SDKROOT = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
SDK_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
SDK_NAME = macosx10.9
(b) PROJECT & SOURCE
PROJECT = HelloWorld
PROJECT_DIR =~/Projects/Learn Objective-C/HelloWorld
PROJECT_FILE_PATH =${PROJECT_DIR}/HelloWorld.xcodeproj
PROJECT_NAME = HelloWorld
SOURCE_ROOT =${PROJECT_DIR}
SRCROOT =${PROJECT_DIR}
(c) BUILD & CONFIGURATION
BUILD_DIR =BUILD_PATH/Products
BUILD_ROOT =BUILD_PATH/Products
BUILT_PRODUCTS_DIR =BUILD_PATH/Products/Debug
CONFIGURATION = Debug
CONFIGURATION_BUILD_DIR =BUILD_PATH/Products/Debug
CONFIGURATION_TEMP_DIR =BUILD_PATH/Intermediates/HelloWorld.build/Debug
(d) PRODUCT & TARGET
PRODUCT_NAME = HelloWorld
PRODUCT_TYPE = com.apple.product-type.tool// Project Template: Command Line Tool
TARGET_BUILD_DIR =BUILD_PATH/Products/Debug
TARGET_NAME = HelloWorld
(3)設置環境變量
Product -> Edit Scheme(option+command+R)->Arguments->Environment Variables中可以添加自定義環境變量(Name為名稱,Value為值)。
在Xcode|Build Phases中Add Run Script Build Phase的Run Script將會使用到環境變量。
7.構建配置
(1)Target & Scheme 一個Target是指在一個Project中構建的一個產品,它包含了構建該產品的所有文件,以及如何構建該產品的配置。 一個定義好構建過程的Target成為一個Scheme,可在Scheme中定義Target的六種構建過程:Build/Run/Test/Profile/Analyze/Archive。 * Run 為編譯運行調試; * Build 為只編譯不運行; *Analyze 用於進行靜態代碼分析,可檢測潛在的內存泄露(不對稱 retain/release 導致的 Potential Leak)或野指針(Use of memory after it is freed)問題。編譯時可選擇 Build Configuration 為 Debug 延用證書配置; * Profile 將調起 Instruments 工具進行動態代碼分析,例如 使用 Allocations/Leaks 動態跟蹤分析內存泄露。編譯時可選擇 Build Configuration 為 Debug沿用證書配置; * Test 用於運行測試,模擬器會啟動並執行測試套件; * Archive 可以Export as Xcode Archive,然后將 .archive 中的 .app 拖入 itunes 可 打包生成 ipa 包。 * Product ->Edit Scheme(編輯配置,快捷鍵為 option+command+R 或 shift+command+,/command+<)->Manage Schemes可對Scheme的六種構建過程進行配置(可配置項包括Info、Arguments、Options)。 * 在 Project Navigator 中選中某個 xcodeproj(例如 QQ.xcodeproj),將進入 Project Setting 頁面,可點擊左側圖標 show/hide project and targets list:

點擊 targets 項可分別設置各 target 的 Build Settings;右擊可對 target 進行 delete。
(2)Build Settings
Architectures:Supported Platforms(OS X、iOS),Base SDK,(Valid)Architectures(armv7、arm64、i386)。
Build Active Architecture Only:一般Debug會選擇YES,表示只是編譯連接調試的目標真機對應的CPU指令集;對於Release Archive版本,需要選擇NO,這樣編譯出來的安裝包才能同時支持在armv7、arm64機型上安裝。
Build Locations:配置構建目錄,包括Intermediate Build Files Path、Build Products Path及其針對Per-Configuration的配置。
Build Options:
Compiler for C/C++/Objective-C默認時Apple LLVM 7.0;
Debug Information Format:真機連接調試時,可斷點定位跟蹤調試,可選擇DWARF以加快編譯速度;但是真機斷開Xcode運行出現crash時,沒有調試符號將無法逆向解析定位出問題的代碼符號及其所在具體位置,故一般要選擇DWARF with dSYM File。
此外還包括Bitcode和Testability兩個使能開關。
Code Signing:包括Entitlements、Identity和Provisioning Profile,詳情參考《iOS Provisioning Profile(Certificate)與Code Signing詳解》。
Deployment:配置發布及安裝選項。
Linking:
Dead Code Stripping:一般對Debug關閉,對Release版本開啟以去除無效路徑僵屍代碼,壓縮安裝包體積。
Display
Mangled Names(LINKER_DISPLAYS_MANGLED_NAMES):針對C++ symbols,ld --no-demangle鏈接開關,一般選擇NO。
Mach-O type:Static Library、Dynamic Library、Executable、Bundle、Relocatable Object File(Position-Dependent )。
Other Linker Flags:例如fobjc-arc(可在Build Rules中針對單個文件配置ARC開關)、-force_load。
Write Link Map File:寫LinkMap文件。
Path to Link Map File:指定鏈接LinkMap文件路徑。
Packaging:
Info.plist File:指定plist文件,對應頂部Info標簽。
Product Name:為應用名稱,例如QQ。
Wrapper Extension:為應用擴展,例如app。
Search Paths:
Info.plist File:指定plist文件,對應頂部Info標簽。
Framework Search Paths: *.framework搜索路徑。
Header Search Paths:*.h/*.hh頭文件搜索路徑。
Library Search Paths:靜態庫、動態庫搜索路徑。
Apple LLVM 7.0配置:
⭐️Code Generation:
Generate Debug Symbols:YES
Optimization Level:優化級別,-Os
⭐️Custom Complier Flags:
⭐️Language
language-Objective-C:Objective-C Automatic Reference Counting,ARC開關。
⭐️Preprocessing:定義Preprocessor Macros,例如DEBUG、NDEBUG=1。
⭐️Warning Policies:例如可以提高警告級別當作錯誤(Treat Warnings as Errors:YES)。
(3)Build Phases
Target Dependencies:設置依賴target。
Copy Bundle Resources:拷貝的資源文件。
Compile Sources:該target需要編譯的源代碼文件。可輸入搜索源代碼文件名(xxx.mm),查看或編輯其編譯選項(Compiler Flags),例如 -fobjc-arc 表示 ARC(__has_feature(objc_arc))。
Link Binary with Libraries:需要鏈接的庫(*.a、*.framework)。
Embed App Extensions:該APP對應的擴展插件。
可以點擊加號,New Run Script Phase,配置custom actions after compiling the Xcode project,相當於Visual Studio的Post-builtstep。
當然,也可以在Edit Scheme中設置Pre-actions(custom actions after compiling the Xcode project)、Post-actions(將在編譯鏈接完成后執行腳本)。
以下Shell腳本將生成的二進制(Unix executable)文件HelloWorld拷貝到~/Software,然后cd到該目錄下並執行HelloWorld:


(4)Build
shift+command+K:清除products|debug或release下的Unix executable文件。
option+shift+command+K:刪除構建目錄(Delete/Clean Build Folder),清理Derived Data對應target目錄下的Build文件夾(包括intermediate和products)。通常用於重新編譯整個工程,嘗試解決增量編譯時部分符號陳舊導致鏈接不通過的問題。
Product -> Edit Scheme(option+command+R)->Info->Build Configuration:選擇生成版本(Debug or Release)
command + B:構建(Buid)
command+8可聚焦左側導航欄中的日志報告導航器,其中可以查看Build日志。
(5)Issue & Errors
command+4可定位Issue Navigator:

當編譯錯誤(error)和警告(warning)過多時,點擊底端的感嘆號,即可忽略編譯警告,只顯示編譯錯誤:

(6)Run command + R:運行(Run),可能會重新編譯鏈接。 option+command + R:如果確定代碼沒有改動,加option鍵可免重新編譯鏈接,直接運行上次build成功的product(Run Without Building)。 command + .:停止運行(Stop)。 (7)Devices & Destination 定義好Target構建配置后,接下來需要指定目標機編譯。 目標機的iPhoneOS.platform必須>=Deployment Target,且Xcode必須支持該機型:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/D eviceSupport/目錄下必須含有對應iOS系統版本的DeveloperDiskImage.dmg,否則真機編譯會提示Could not find developer disk image。 shift+command+2:可以查看當前連接的Device和支持的Simulator。 control+option+command+[/]:Select Previous/Next Destination,在連接多個真機或模擬器之間切換。
8.運行調試
(1)Target & Scheme
一個Target是指在一個Project中構建的一個產品,它包含了構建該產品的所有文件,以及如何構建該產品的配置。
一個定義好構建過程的Target成為一個Scheme,可在Scheme中定義Target的六種構建過程:Build/Run/Test/Profile/Analyze/Archive。
Run 為編譯運行調試;
Build 為只編譯不運行;
Analyze 用於進行靜態代碼分析,可檢測潛在的內存泄露(不對稱 retain/release 導致的 Potential Leak)或野指針(Use of memory after it is freed)問題。
編譯時可選擇 Build Configuration 為 Debug 延用證書配置;
Profile 將調起 Instruments 工具進行動態代碼分析,例如 使用 Allocations/Leaks 動態跟蹤分析內存泄露。編譯時可選擇 Build Configuration 為 Debug沿用證書配置;
Test 用於運行測試,模擬器會啟動並執行測試套件;
Archive 可以Export as Xcode Archive,然后將 .archive 中的 .app 拖入 itunes 可 打包生成 ipa 包。
Product ->Edit Scheme(編輯配置,快捷鍵為 option+command+R 或 shift+command+,/command+<)->Manage Schemes可對Scheme的六種構建過程進行配置(可配置項包括Info、Arguments、Options)。
在 Project Navigator 中選中某個 xcodeproj(例如 QQ.xcodeproj),將進入 Project Setting 頁面,可點擊左側圖標 show/hide project and targets list:
點擊 targets 項可分別設置各 target 的 Build Settings;右擊可對 target 進行 delete。
(2)Build Settings
Architectures:Supported Platforms(OS X、iOS),Base SDK,(Valid)Architectures(armv7、arm64、i386)。
Build Active Architecture Only:一般Debug會選擇YES,表示只是編譯連接調試的目標真機對應的CPU指令集;對於Release Archive版本,需要選擇NO,這樣編譯出來的安裝包才能同時支持在armv7、arm64機型上安裝。
Build Locations:配置構建目錄,包括Intermediate Build Files Path、Build Products Path及其針對Per-Configuration的配置。
Build Options:
Compiler for C/C++/Objective-C默認時Apple LLVM 7.0;
Debug Information Format:真機連接調試時,可斷點定位跟蹤調試,可選擇DWARF以加快編譯速度;但是真機斷開Xcode運行出現crash時,沒有調試符號將無法逆向解析定位出問題的代碼符號及其所在具體位置,故一般要選擇DWARF with dSYM File。
此外還包括Bitcode和Testability兩個使能開關。
Code Signing:包括Entitlements、Identity和Provisioning Profile,詳情參考《iOS Provisioning Profile(Certificate)與Code Signing詳解》。
Deployment:配置發布及安裝選項。
Linking:
Dead Code Stripping:一般對Debug關閉,對Release版本開啟以去除無效路徑僵屍代碼,壓縮安裝包體積。
Display
Mangled Names(LINKER_DISPLAYS_MANGLED_NAMES):針對C++ symbols,ld --no-demangle鏈接開關,一般選擇NO。
Mach-O type:Static Library、Dynamic Library、Executable、Bundle、Relocatable Object File(Position-Dependent )。
Other Linker Flags:例如fobjc-arc(可在Build Rules中針對單個文件配置ARC開關)、-force_load。
Write Link Map File:寫LinkMap文件。
Path to Link Map File:指定鏈接LinkMap文件路徑。
Packaging:
Info.plist File:指定plist文件,對應頂部Info標簽。
Product Name:為應用名稱,例如QQ。
Wrapper Extension:為應用擴展,例如app。
Search Paths:
Info.plist File:指定plist文件,對應頂部Info標簽。
Framework Search Paths: *.framework搜索路徑。
Header Search Paths:*.h/*.hh頭文件搜索路徑。
Library Search Paths:靜態庫、動態庫搜索路徑。
Apple LLVM 7.0配置:
⭐️Code Generation:
Generate Debug Symbols:YES
Optimization Level:優化級別,-Os
⭐️Custom Complier Flags:
⭐️Language
language-Objective-C:Objective-C Automatic Reference Counting,ARC開關。
⭐️Preprocessing:定義Preprocessor Macros,例如DEBUG、NDEBUG=1。
⭐️Warning Policies:例如可以提高警告級別當作錯誤(Treat Warnings as Errors:YES)。
(3)Build Phases
Target Dependencies:設置依賴target。
Copy Bundle Resources:拷貝的資源文件。
Compile Sources:該target需要編譯的源代碼文件。可輸入搜索源代碼文件名(xxx.mm),查看或編輯其編譯選項(Compiler Flags),例如 -fobjc-arc 表示 ARC(__has_feature(objc_arc))。
Link Binary with Libraries:需要鏈接的庫(*.a、*.framework)。
Embed App Extensions:該APP對應的擴展插件。
可以點擊加號,New Run Script Phase,配置custom actions after compiling the Xcode project,相當於Visual Studio的Post-builtstep。
當然,也可以在Edit Scheme中設置Pre-actions(custom actions after compiling the Xcode project)、Post-actions(將在編譯鏈接完成后執行腳本)。
以下Shell腳本將生成的二進制(Unix executable)文件HelloWorld拷貝到~/Software,然后cd到該目錄下並執行HelloWorld:


(4)Build
shift+command+K:清除products|debug或release下的Unix executable文件。
option+shift+command+K:刪除構建目錄(Delete/Clean Build Folder),清理Derived Data對應target目錄下的Build文件夾(包括intermediate和products)。
通常用於重新編譯整個工程,嘗試解決增量編譯時部分符號陳舊導致鏈接不通過的問題。
Product -> Edit Scheme(option+command+R)->Info->Build Configuration:選擇生成版本(Debug or Release)
command + B:構建(Buid)
command+8可聚焦左側導航欄中的日志報告導航器,其中可以查看Build日志。
(5)Issue & Errors
command+4可定位Issue Navigator:

當編譯錯誤(error)和警告(warning)過多時,點擊底端的感嘆號,即可忽略編譯警告,只顯示編譯錯誤:

(6)Run command + R:運行(Run),可能會重新編譯鏈接。 option+command + R:如果確定代碼沒有改動,加option鍵可免重新編譯鏈接,直接運行上次build成功的 product(Run Without Building)。 command + .:停止運行(Stop)。 (7)Devices & Destination 定義好Target構建配置后,接下來需要指定目標機編譯。 目標機的iPhoneOS.platform必須>=Deployment Target,且Xcode必須支持該機型:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/目錄下必須含有對應iOS系統版本的DeveloperDiskImage.dmg,否則真機編譯會提示Could not find developer disk image。 shift+command+2:可以查看當前連接的Device和支持的Simulator。 control+option+command+[/]:Select Previous/Next Destination,在連接多個真機或模擬器之間切換。
8.運行調試
(1)Console
* shift+command+Y:顯示控制台(Show/Hide the debug area)
* shift+command+C:激活聚焦控制台,光標定位到控制台呈可輸入狀態
* command+K:清除控制台(Debug->Debug Workflow->Clear Console)
可安裝BBUDebuggerTuckAway插件,在打字coding時,自動隱藏調試控制台
(2)Breakpoint
* command + \:當前行設置/取消斷點;通過鼠標點擊邊列中的藍色斷點來啟用/禁用當前行斷點。
* command + Y:全局激活或禁用所有的斷點,激活進入調試模式(此時斷點藍色可見)。
* 邊列(Gutter)中的斷點/警告可右鍵呼出Reveal in Breakpoint/Issue Navigator。
* trick:編輯斷點(Edit Breakpoint):
* Condition:設置斷點的觸發條件,例如“i==3”(注意不能有空格)表示當i等於3時該斷點才會被觸發。
* Ignore:設置斷點需要被忽略多少次才會中斷,若設置成5則表示第6次遇到該斷點時才觸發。
* Action:設置斷點觸發時的動作,可以為Debugger Command、Log Message、Shell Command或Sound。
例如可設置以下Debugger Command:
[1]讀取std::string sig的內存buffer值:mem read sig.c_str() -c sig.size();
[2]打印NSData實例sig:po sig
(3)Debug
* F6:下一步(Step Over),逐過程單步調試,不進入函數體。
* (fn+)F7:進入(Step Into)函數體。可能與多媒體鍵有沖突,故需要fn輔助(建議將功能鍵F1-F12設置為標准的功能鍵)。
* (fn+)F8:跳出(Step Out)函數體。可能與多媒體鍵有沖突,例如呼叫iTunes,故需要fn輔助。
* control+command+Y:逐斷點繼續執行(Pause/Continue)。
* control+command+C:執行到當前光標所在行(Continue to current line)。
* trick:移動指令指針(Move the instruction pointer):
* 斷點調試運行時,可以將綠色指針箭頭(Line 47)移動到其他行(Line 49)或其他斷點(Line 51)實現跳轉執行。
command+8可聚焦左側導航欄中的日志報告導航器,其中可以查看Debug日志。
(4)Watch
* shift+command+M:Debug Workflow->View Memory。
* Debug Workflow->Show Disassembly When Debugging,可進行匯編指令級調試。
* trick:修改變量內存值(change memory value while debugging):
* 調試運行時,可以在底部的調試窗口(Debug Area,可通過Shift+Command+Y呼出)右鍵某個變量,除了可以進行View Memory/View Value As之外,還可以選擇Edit Value運行時編輯內存變量的值。
* 在調試驗證某些難以復現的bug或進行邊界測試時非常有用,可減少每次修改測量樣本值(hardcode)重新編譯鏈接的痛苦。
(5)lldb調試命令
* n/next:step over,等效於F6;
* s/step:step into,等效於(fn+)F7;
* finish:step out,等效於(fn+)F8;
* c/continue:goto next breakpoint,等效於^⌘Y;
* expr/expression:Evaluate a C/ObjC/C++ expression(動態執行C/ObjC/C++表達式);
* p/print/expr/expression:print as a C/C++ basic variable;
// 打印SYSTEM_VERSION(可能要加UIDevice*轉換)
* (lldb)p [[[UIDevicecurrentDevice] systemVersion] doubleValue]
* po/expr -O/expression -O:Print as an Objective-C object;
// 打印屏幕bounds(可能要加UIScreen*轉換)
* (lldb)po NSStringFromCGRect([[UIScreen mainScreen] bounds])
// 打印狀態欄frame(可能要加UIApplication*轉換)
* (lldb)po NSStringFromCGRect([UIApplication sharedApplication].statusBarFrame)
// 打印當前keyWindow的根視圖(可能要加UIViewController*轉換)
* (lldb)po [[[UIApplication sharedApplication] keyWindow] rootViewController]
* call:調用。其實上述p/po后接表達式(expression)也有調用的功能,一般只在不需要顯式輸出,或是無返回值時使用call,用於動態調試插入調用代碼。
例如可以在viewDidLoad:里面設置斷點,然后在程序中斷的時候輸入以下命令:
// 調用后,繼續運行程序,view的背景色將變成紅色
* (lldb) call [self.view setBackgroundColor:[UIColor redColor]]
* bt(backtrace),打印當前調用堆棧(crash堆棧),“bt all”可打印所有thread的堆棧(相當於command+6的Debug Session Navigation)。
* image:可用於尋址,有多個組合命令,比較實用的一種用法是尋找棧地址對應的代碼(行)位置。
例如某個UITableView總共有2個section,當其引用的currentSection.index≥2時將會引起[UITableView rectForHeaderInSection:]調用異常,可使用expr動態改值制造crash場景模擬調試。
此時crash時的控制台bt顯示異常出現在應用層代碼“0x00d055b8 - [FACategoryTableView FACategorySectionHeaderDidTouched:] +744”處(其中0x00d055b8為當前棧(代碼段)偏移量,744為棧幀偏移量——PC指針相對函數入口的偏移)。
那么具體是FACategoryTableView.m文件哪一行代碼調用引起的異常呢?此時通過“image lookup --address”后接bt的call stack中的代碼段偏移地址(0x00d055b8)即可定位出異常調用的代碼行位置。
* x/memory read:dump指定地址的內存(Read from the memory of the process being debugged),后接起止地址或-c指定count加起始地址。可help mem read查看幫助:
Syntax:
memory read <cmd-options> <address-expression> [<address-expression>]
Command Options Usage:
size指定內存塊(block/chunk)的大小
--size <byte-size> ):The size in bytes to use when displaying with the selected format.
count指定內存塊(block/item)的個數,可配合起始地址使用。
-c <count> ( --count <count> ):The number of total items to display.
format指定內容顯示格式,格式符同print:c-char,s-string,d-decimal,x-hex。
-f <format> ( --format <format> ):Specify a format to be used for display.
Command Samples:
(a)起止地址,以下基於起始地址偏移量指定截至地址。
(lldb)mem read 0x10b88f0c 0x10b88f0c+9
0x10b88f0c: 39 38 37 36 35 34 33 32 31 987654321
(b)可在起始地址后使用-c指定需要dump的字節數,以上等效:
(lldb)mem read 0x10b88f0c -c 9
0x10b88f0c: 39 38 37 36 35 34 33 32 31 987654321
(c)起始地址+內存塊size+內存塊count(dump hex format)
(lldb)memory read -s 1 -f x -c 9 0x10b88f0c
0x10b88f0c: 0x39 0x38 0x37 0x36 0x35 0x34 0x33 0x32
0x10b88f14: 0x31
說明:dump的memory chunk為1byte,以上總共dump了chunk size*chunk count=9byte。
(d)起始地址+內存塊size+內存塊count(dump char format)
(lldb)memory read -s 1 -f c -c 9 0x10b88f0c
0x10b88f0c: 987654321
(e)起始地址+內存塊size+內存塊count(dump string format)
(lldb)mem read 0x10b5cf2c -f s -c 1
0x10b88f0c: "987654321"
(f)起始地址+內存塊size+內存塊count(dump int format)
(lldb)memory read -s 4 -f x -c 3 0x10b88f0c
0x10b88f0c: 0x36373839 0x32333435 0x109f0031
說明:以上指定chunk尺寸為4byte(-s 4),chunk數量為3,共dump了12個byte。
memory write:改寫指定地址的內存(Write to the memory of the process being debugged)。可自行help mem write查看幫助:
Syntax: memory write <cmd-options> <address> <value> [<value> [...]]
trick:lldb打印無效問題
在使用LLDB調試命令p/po打印C類型(包括復合類型)或Objective-C對象時,可能會遇到屬性不存在或類型不匹配的問題。
例1——斷點調試,打印當前UIViewController的frame:
由於Xcode lldb本身的bug,對屬性的點引用有時會無法識別,例如執行(lldb) p self.view.frame報錯:property 'frame' not found on object of type 'UIView *'
將對屬性的點引用改為對屬性的getter調用,執行(lldb) p [self.view frame]依舊報錯:no known method '-frame'; cast the message send to the method's return type
由於Xcode lldb本身的bug,對返回的復合類型也無法直接識別,此時可采用顯示類型轉換,執行(lldb) p (CGRect)[self.view frame]不會報錯!

例2——斷點調試,打印當前UIViewController的navigationController堆棧和childViewControllers數組:
點引用報錯寫法(property not found):(lldb) po self.navigationController.viewControllers
調用getter正確打印:(lldb) po [[self navigationController] viewControllers]
點引用報錯寫法(property not found):(lldb) po self.childViewControllers
調用getter正確打印:(lldb) po [self childViewControllers]
(6)啟用NSZombieEnabled調試EXC_BAD_ACCESS
當你對已釋放的對象發送消息(90%的可能是對引用計數為0的對象再release)或release那些autorelease對象時,就會出現報EXC_BAD_ACCESS這樣的錯誤。
默認設置下 Xcode不會給你定位具體是哪一行代碼不該去使用已釋放的對象,或者release用錯了。
Product -> Edit Scheme(option+command+R) -> Diagnostics ,勾選“Objective-C”之后的“Enable Zombie Objects”。
設置NSZombieEnabled環境變量后,一個對象銷毀時會被轉化為_NSZombie;設置NSZombieEnabled后,當你向一個已經釋放的對象發送消息,這個對象就不只是報EXC_BAD_ACCESS Crash,還會放出一個錯誤消息,然后以一種可預測的可以產生debug斷點的方式消失, 因此我們可以找到具體或者大概是哪個對象被錯誤的釋放或引用了。
注意:NSZombieEnabled只能在調試的時候使用,千萬不要忘記在產品發布的時候去掉,因為NSZombieEnabled不會真正去釋放dealloc對象的內存,一直開啟后果自負!
參考:https://blog.csdn.net/hitfyb/article/details/50875690
