XCode使用一:Xcode基本操作
說(shuō)明:從左到右少欺,依次是“導(dǎo)航窗格(Navigator)->邊列(Gutter)->焦點(diǎn)列(Ribbon)->代碼編輯窗口(Standard/Primary Editor)”。
邊列(Gutter):顯示行號(hào)和斷點(diǎn)哀蘑。
焦點(diǎn)列(Ribbon):灰色深度與代碼嵌套深度相關(guān):鼠標(biāo)懸停可突出顯示右側(cè)相應(yīng)代碼塊(Focus
code blocks on hover),鼠標(biāo)單擊可折疊右側(cè)相應(yīng)代碼塊(Code folding)。
通過(guò)“command+,”快捷鍵或”Xcode|Preferences”菜單呼出偏好設(shè)置。
(1)主題及字體(Preferences->Fonts & Colors)
選中一種主題(theme)片择,例如“Midnight”,推薦使用Monokai骚揍、Ciapre字管。將 `*.dvtcolortheme` 文件拷貝到 `~/Library/Developer/Xcode/UserData/FontAndColorThemes/`即可安裝主題, 重啟 Xcode 即可選用信不。
Xcode默認(rèn)字體為menlo嘲叔,也可選擇 Consolas、Monaco抽活、Consolas硫戈、Droid Sans Mono、Source Code Pro下硕、Bitstream Vera Sans?等其他等寬字體丁逝。
shift 選擇主題 Source Editor/Console 中的所有項(xiàng),點(diǎn)擊 Fonts 可更改字體(大兴笮铡)霜幼。
(2)編輯器配置(Preferences->Text Editing)
Editing:
Show Line Numbers:在gutter中顯示行號(hào)。
Code folding ribbon:顯示焦點(diǎn)列誉尖。
Focus code blocks on hover:鼠標(biāo)懸停時(shí)突出顯示右側(cè)相應(yīng)代碼塊罪既。
Page guide at column:顯示一行最多支持80個(gè)字符的提示分割線。
Indentation:
Prefer indent using:Spaces(為保持一致的視覺(jué)呈現(xiàn)和行末注釋對(duì)齊铡恕,建議使用空格)
Tab width:4 spaces(tab expand琢感,1個(gè)tab=4個(gè)空格)
Indent width:4 spaces(自動(dòng)縮進(jìn)步長(zhǎng)=4個(gè)空格)
(3)跳轉(zhuǎn)打開(kāi)方式(Preferences->Navigation)
Activation:When a tab or window opens,make it active探熔。當(dāng)新建窗口或標(biāo)簽時(shí)驹针,立即激活聚焦。
Navigation:Uses Primary/Focused Editor诀艰。打開(kāi)Project Navigator中指定的文件時(shí)牌捷,在主編輯器窗口/當(dāng)前聚焦窗口打開(kāi),建議選擇Focused涡驮。
Optional Navigation:Uses Single Assistant Editor。打開(kāi)Project Navigator中指定的文件或跳轉(zhuǎn)到符號(hào)定義所在文件(command+單擊)時(shí)喜滨,若按下option鍵捉捅,則在輔助窗口打開(kāi)。
Double Click Navigation:Uses Separate Tab虽风。雙擊打開(kāi)Project Navigator中指定的文件或跳轉(zhuǎn)到符號(hào)定義所在文件(command+雙擊)時(shí)棒口,新建標(biāo)簽頁(yè)寄月。
(4)SCM(Preferences->Source Control)
Enable Source Control:?jiǎn)⒂?禁用Xcode自帶Source Control Manager(SCM)。
Comparison View:Show local revision in [Right] Side无牵。打開(kāi)version editor比較窗口時(shí)漾肮,左側(cè)顯示服務(wù)器基線版本(base),[右側(cè)]顯示本地修改過(guò)的工作拷貝(local working copy)茎毁。
(5)SDK/Simulator(Preferences->Downloads)
Downloads:可下載Components(SDK&Simulator)和Documentation克懊。
(6)構(gòu)建輸出目錄(Preferences->Locations->Locations)
當(dāng)選擇為Default時(shí),Derived Data的目錄為~/Library/Developer/Xcode/DerivedData七蜘。
當(dāng)選擇為Relative時(shí)谭溉,Derived Data的目錄為當(dāng)前*.xcodeproj所在的目錄。
當(dāng)選擇為Custom時(shí)橡卤,Derived Data的目錄需自定義扮念。
不建議使用絕對(duì)路徑,因?yàn)閷?xiě)死之后碧库,換環(huán)境或換平臺(tái)柜与,又要重新修改路徑,且同名project target的build folder會(huì)覆蓋嵌灰,建議使用相對(duì)路徑(Relative)
option+點(diǎn)按:查看選中符號(hào)的幫助提示(Quick Help for Selected Item)弄匕。
option+雙擊:打開(kāi)選中符號(hào)的幫助文檔。
command+0:Show/Hide left tool panel(Navigator Area)
command+1-8:Project/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隱藏左側(cè)欄Navigator伞鲫,再按下option+command+0隱藏右側(cè)欄Utility粘茄,只顯示Standard/Primary Editor,聚焦有效利用屏幕進(jìn)行編碼秕脓。
control+1:Show Related Items(例如Superclasses/Subclasses柒瓣、Callers/Callees、ProtocolImplementor/Implemented吠架、Includes/Included By)芙贫。可輸入實(shí)時(shí)搜索匹配傍药。
control+2/3:ShowPrevious/NextHistory磺平。可輸入實(shí)時(shí)搜索匹配拐辽。
control+4:Show Top Level Items拣挪。
control+5:Show Group Files(當(dāng)前文件夾內(nèi)的所有文件)【阒睿可輸入實(shí)時(shí)搜索匹配菠劝。
control+6:Show DocumentItems(當(dāng)前文件的Symbols)≌龃睿可輸入實(shí)時(shí)搜索匹配赶诊。
command+shift+[/]:切換標(biāo)簽頁(yè)
單/雙指左右滑動(dòng)(control+command+←/→):在單標(biāo)簽頁(yè)打開(kāi)的多個(gè)文件間切換(Go Back/Forward)
command+L:跳轉(zhuǎn)到指定行笼平。
shift+command+O:Open Quickly,快速全局查找文件舔痪、符號(hào)寓调,非常常用!
command+點(diǎn)擊Editor中選中的符號(hào):跳轉(zhuǎn)到符號(hào)定義(jump to definition)锄码。
control+command+J:跳轉(zhuǎn)到指定符號(hào)的定義處或?qū)崿F(xiàn)處(Go to Declaration/Definition)夺英。有時(shí)工程正在Loading、Indexing或Processing files時(shí)巍耗,“command+點(diǎn)擊”無(wú)法響應(yīng)秋麸,此時(shí)可試試control+command+J。
control+command+↑/↓:切換頭文件/實(shí)現(xiàn)文件(switch between a source file (.m,*.mm,*.cc) and the associated header?file(.h)炬太,Jump to?Previous/NextCounterpart)灸蟆。
在Project Navigator中選中文件右鍵或通過(guò)菜單“File->Show in Finder”:在Finder中定位該文件。
command+2可聚焦左側(cè)導(dǎo)航欄中的符號(hào)導(dǎo)航器亲族。
filter0:底部編輯框輸入符號(hào)(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霎迫,過(guò)濾顯示當(dāng)前工程中的符號(hào)斋枢。filter2的結(jié)果是filter1的子集,較常用知给。
filter3:show only containers(hide members)瓤帚,過(guò)濾顯示包含該單詞的符號(hào)。
注意:control+6只列出當(dāng)前代碼所在interface的符號(hào)涩赢,而Symbol Navigator是當(dāng)前工程(Project Scope)的所有符號(hào)列表的Hierarchy戈次,符號(hào)種類(lèi)包括Classes/Protocols/Functions/Structs/Unions/Enums/Types/Globals。
編輯器中光標(biāo)所在符號(hào)處筒扒,Navigate菜單或右鍵快捷菜單可[Reveal?inSymbol Navigator]怯邪,在符號(hào)導(dǎo)航器中定位當(dāng)前符號(hào),亦可查看當(dāng)前符號(hào)所屬類(lèi)的層次花墩。
option+command+←/→:折疊當(dāng)前代碼塊悬秉,包括@interface …@end、@implementation …@end
option+shift+command+←/→:折疊該文件內(nèi)所有代碼塊(方法/函數(shù):{?Methods&Functions})
control+shift+command+←/→:折疊當(dāng)前注釋塊(/*Comment Blocks*/)
(shift+)option+command+`:MoveFocusto (Previous)Next Area.
command+J:焦點(diǎn)切換(Move Focus)冰蘑,可配合鼠標(biāo)和方向鍵和泌。帶‘+’的“Move focus to a new assistant editor”可以快速在輔助編輯窗口中打開(kāi)頭文件(*.h)/實(shí)現(xiàn)文件(*.m,*.mm)祠肥。
shift+command+J:在項(xiàng)目導(dǎo)航中定位當(dāng)前編輯其中打開(kāi)的文件(Reveal in Project Navigator)允跑。
control+command+N:File | New | Workspace
shift+command+N:File | New | Project
command+X/C/V:剪切/復(fù)制/粘貼
command+Z(+shift):撤銷(xiāo)(重做)/Undo(Redo)
command+[/]:向前/向后縮進(jìn)(Shift Left/Right)
option+command+[/]:將當(dāng)前光標(biāo)所在行代碼上移/下移一行(Move Line Up/Down)
command+/:以雙斜杠(//)注釋選中的代碼,再此按下可取消
Parentheses/Brackets/Braces Matching:雙擊某個(gè)分隔符(如()、[]聋丝、{}?等),Xcode會(huì)選中匹配代碼塊工碾。
Editor→Structure→Balance Delimiter:根據(jù)當(dāng)前光標(biāo)代碼所在位置弱睦,自動(dòng)向外擴(kuò)展選擇外層代碼塊。
esc(control+.)就當(dāng)前輸入上下文呼出/隱藏智能提示列表(Auto
Completion List)渊额;
上下方向鍵(↑/↓)在智能提示列表中選擇選項(xiàng)况木。當(dāng)然,也可以用control+.旬迹;enter選中列表中備選的消息符號(hào)火惊;
tab在輸入符號(hào)不完整時(shí)可一截一截匹配;選中消息符號(hào)后奔垦,tab可在各個(gè)參數(shù)占位符之間移動(dòng)屹耐,enter可選中參數(shù)占位符先臨時(shí)補(bǔ)位填充。
輸入Objective-C對(duì)象及消息名椿猎,然后輸入?]惶岭,自動(dòng)補(bǔ)充對(duì)象名左側(cè)的[,完成中綴符(infix natation)包圍犯眠。
當(dāng)鼠標(biāo)定位或選中某個(gè)符號(hào)時(shí)按灶,可呼叫右鍵快捷菜單:
Find SelectedTextinWorkspace:在當(dāng)前工作空間查找選中文本或光標(biāo)所在行的OC冒號(hào)分割方法名。
Find SelectedSymbolinWorkspace:在當(dāng)前工作空間查找選中文本符號(hào)或光標(biāo)所在行的OC冒號(hào)分割方法符號(hào)筐咧。
FindCall?Hierarchy:查找選中文本符號(hào)或光標(biāo)所在行的OC冒號(hào)分割方法符號(hào)的調(diào)用著(Callers)鸯旁。
對(duì)應(yīng)Find菜單中有Find SelectedTextinProject、Find SelectedSymbolinProject(control+shift+command+F)量蕊、FindCall?Hierarchy(control+shift+command+H)铺罢。
說(shuō)明:Find Call Hierarchy等效于control+1|Callers。
command+F:當(dāng)前文件查找危融。
shift+command+F(command+3):在Find Navigator中全局查找畏铆。可在[Preferences-General]中設(shè)置Find Navigator Detail的顯示行數(shù)(當(dāng)Navigator Area較窄擠壓時(shí))吉殃。
Find:可指定查找內(nèi)容(Text/References/Definitions/Regular Expression)辞居;
放大鏡:下拉可查看最近查找歷史;
In Project:查找范圍(可指定Group)蛋勺;
Text:匹配規(guī)則(可指定Containing瓦灶,Matching,Starting with抱完,Ending with)贼陶;
Case:是否區(qū)分大小寫(xiě)(可指定 Matching/Ignoring)。
對(duì)于查找出來(lái)的結(jié)果可以delete刪除非預(yù)期干擾結(jié)果條目,也可以多擇或全選Find Results拷貝出來(lái)整理分析碉怔。
option+command+F:當(dāng)前文件替換烘贴。
option+shift+command+F:在Find Navigator中全局替換。
Replace:逐個(gè)替換撮胧;
All:所有替換桨踪;
Done:替換完成。
例如芹啥,光標(biāo)停留在NSMutableArray的insertObject:atIndex的前半截單詞insertObject上時(shí):
有三種復(fù)制方式:
command+C:Copy(光標(biāo)所在位置的單詞):insertObject
control+shift+command+C:Copy Symbol Name(光標(biāo)所在位置的消息符號(hào)名稱(chēng)):-insertObject:atIndex:
option+control+shift+command+C:Copy Qualified Symbol Name(光標(biāo)所在位置的消息符號(hào)全名锻离,帶所屬類(lèi)名):-[NSMutableArray insertObject:atIndex:]
通過(guò)后兩種快捷方式,可以便捷地復(fù)制Objective-C特殊的冒號(hào)分隔的消息符號(hào)名稱(chēng)墓怀。
(7)Open with External Editor——SublimeText
<1>在左側(cè)導(dǎo)航欄(Project Navigator)中選中某個(gè)文件右鍵快捷菜單中有【Open with External Editor】汽纠,默認(rèn)呼叫Mac OS X自帶的文本編輯器(TextEdit)打開(kāi)。我們可以按照以下步驟設(shè)置快捷鍵:
【系統(tǒng)偏好設(shè)置(System Preferences)->鍵盤(pán)(Keyboard)->快捷鍵(Shortcuts)->應(yīng)用快捷鍵(App Shortcuts)】傀履,
點(diǎn)擊+號(hào)虱朵,選擇應(yīng)用程序【Xcode.app】
準(zhǔn)確填寫(xiě)[菜單標(biāo)題],即菜單命令名稱(chēng)【Open with External Editor】啤呼,聚焦[鍵盤(pán)快捷鍵]編輯框時(shí)卧秘,同時(shí)按下想要設(shè)置的組合鍵即可,例如option+command+O(??O)官扣。
可針對(duì)Xcode工程代碼文件(*.h/*.hh/*.c/*.cc/*.m/*.mm)設(shè)置默認(rèn)打開(kāi)程序?yàn)镾ublime Text.app:右鍵Get Info(command+I)翅敌,Open With選擇Sublime Text.app并且Change All。然后惕蹄,Xcode|Open with External Editor將在Sublime Text打開(kāi)選中文件蚯涮。
<2>另外,可下載安裝OpenInSublimeText插件卖陵,支持呼叫SublimeText打開(kāi)Xcode當(dāng)前正在編輯的文件遭顶。
從github下載打開(kāi)OpenInSublimeText.xcodeproj工程進(jìn)行編譯(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]項(xiàng)撩荣,可設(shè)置其快捷鍵位為shift+command+S(??S)铣揉。
Assistant Editor有點(diǎn)類(lèi)似VC中的Code Definition Window,可實(shí)現(xiàn)分屏查看代碼Counterpart餐曹,方便交叉參考代碼編輯逛拱。
option+command+enter/,:打開(kāi)Assistant Editor。
command+enter:關(guān)閉Assistant Editor台猴。
可通過(guò)菜單[View|Assistant Editor]設(shè)置Assistant Editors的方向朽合,例如On Right俱两。
在Mac OS X日常操作中,我們已經(jīng)認(rèn)識(shí)到option這把單刀雙擲開(kāi)關(guān)的妙用:按住鼠標(biāo)移動(dòng)或三指觸控移動(dòng)時(shí)曹步,按下option鍵可實(shí)現(xiàn)豎直塊選宪彩;調(diào)節(jié)音量/亮度時(shí),按住option+shift可以四分之一單位微調(diào)箭窜。
使用Xcode快捷鍵進(jìn)行切換或跳轉(zhuǎn)動(dòng)作時(shí)毯焕,若同時(shí)按下option可以在輔助編輯窗口中打開(kāi)相應(yīng)文件或符號(hào)(For optional navigation (Option-clickingorOption-choosinga file), opens the file in a new Assistant editor pane.)。若在輔助窗口中操作,則在主窗口(Standard Editor)中打開(kāi)。
option+點(diǎn)擊Project Navigator中選中的文件:在輔助編輯窗口中打開(kāi)選中文件虱岂。
option+command+點(diǎn)擊Editor中選中的符號(hào):在輔助編輯窗口中打開(kāi)符號(hào)定義(jump to definition in assistant editor)筷屡。
option+control+command+↑/↓:在輔助窗口中打開(kāi)對(duì)應(yīng)的頭文件(*.h)/實(shí)現(xiàn)文件(*.m,*.mm,*.cc)。
點(diǎn)擊查看shift+command+O尚骄、shift+command+F(command+3)選中的文件或符號(hào)時(shí)块差,可同時(shí)按下option在輔助編輯窗口中打開(kāi)。
在control+1~6中打開(kāi)選擇結(jié)果時(shí)倔丈,均可同時(shí)按下option在輔助編輯窗口中打開(kāi)憨闰。
在Xcode以上種種切換跳轉(zhuǎn)操作時(shí),按下option的同時(shí)按下shift需五,通常會(huì)呼出一個(gè)導(dǎo)航窗格(option+command+<)鹉动,可選擇在new window/tab/assistant-editor打開(kāi)顯示。
ForOption-Shiftnavigation (Option-Shift-clickor Option-Shift-choosea file), Xcode displays a graphical navigation chooser showing the current layout. The chooserpromptsyou to open the file in anyopeneditor pane in any window and tab, or to open the file in aneweditor pane, window, or tab.
6.環(huán)境變量(Build Setting Macros)
命令行進(jìn)入HelloWorld工程目錄宏邮,執(zhí)行xcodebuild命令并帶上“-showBuildSettings”參數(shù):
$xcodebuild?-projectHelloWorld.xcodeproj-targetHelloWorld-configurationDebug-showBuildSettings> xcodebuild_showBuildSettings.txt
則xcodebuild_showBuildSettings.txt中保存了Build settings for action build and target "HelloWorld”泽示,其中dump了所有的環(huán)境變量。
(2)Xcode5(Mac OS X 10.9)的部分環(huán)境變量
約定1:~=當(dāng)前賬戶的HOME目錄蜜氨,例如“/Users/faner”械筛。
約定2:build構(gòu)建基礎(chǔ)路徑:BUILD_PATH= ~/Library/Developer/Xcode/DerivedData/Build§祝可通過(guò)“File->Project Settings”查看Derived Data Location埋哟。
約定3:環(huán)境變量宏(Build Setting Macros)引用格式:${MACRO},同Build Phases Run Script中的語(yǔ)法郎汪。
下面是摘選自xcodebuild_showBuildSettings.txt的部分常用環(huán)境變量赤赊。
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
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}
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
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
Product -> Edit Scheme(option+command+R)->Arguments->Environment Variables中可以添加自定義環(huán)境變量(Name為名稱(chēng),Value為值)怒竿。
在Xcode|Build Phases中Add Run Script Build Phase的Run Script將會(huì)使用到環(huán)境變量砍鸠。
一個(gè)Target是指在一個(gè)Project中構(gòu)建的一個(gè)產(chǎn)品,它包含了構(gòu)建該產(chǎn)品的所有文件耕驰,以及如何構(gòu)建該產(chǎn)品的配置爷辱。
一個(gè)定義好構(gòu)建過(guò)程的Target成為一個(gè)Scheme,可在Scheme中定義Target的六種構(gòu)建過(guò)程:Build/Run/Test/Profile/Analyze/Archive。
Run為編譯運(yùn)行調(diào)試饭弓;
Build為只編譯不運(yùn)行双饥;
Analyze?用于進(jìn)行靜態(tài)代碼分析,可檢測(cè)潛在的內(nèi)存泄露(不對(duì)稱(chēng)?retain/release 導(dǎo)致的 Potential Leak)或野指針(Use of memory after it is freed)問(wèn)題弟断。編譯時(shí)可選擇 Build Configuration 為 Debug 沿用證書(shū)配置咏花;
Profile?將調(diào)起 Instruments 工具進(jìn)行動(dòng)態(tài)代碼分析,例如?使用?Allocations/Leaks 動(dòng)態(tài)跟蹤分析內(nèi)存泄露阀趴。編譯時(shí)可選擇 Build Configuration 為 Debug沿用證書(shū)配置昏翰;
Test用于運(yùn)行測(cè)試,模擬器會(huì)啟動(dòng)并執(zhí)行測(cè)試套件刘急;
Archive?可以Export as Xcode Archive棚菊,然后將 .archive 中的 .app 拖入 itunes?可?打包生成 ipa 包。
Product ->Edit Scheme(編輯配置叔汁,快捷鍵為option+command+R?或 shift+command+,/command+<)->Manage Schemes可對(duì)Scheme的六種構(gòu)建過(guò)程進(jìn)行配置(可配置項(xiàng)包括Info统求、Arguments、Options)据块。
在 Project Navigator 中選中某個(gè) xcodeproj(例如 QQ.xcodeproj)码邻,將進(jìn)入 Project Setting 頁(yè)面,可點(diǎn)擊左側(cè)圖標(biāo) show/hide project and targets list:
點(diǎn)擊 targets 項(xiàng)可分別設(shè)置各 target 的 Build Settings另假;右擊可對(duì) target 進(jìn)行 delete像屋。
Architectures:Supported Platforms(OS X、iOS)浪谴,Base SDK开睡,(Valid)Architectures(armv7、arm64苟耻、i386)篇恒。
Build Active Architecture Only:一般Debug會(huì)選擇YES,表示只是編譯連接調(diào)試的目標(biāo)真機(jī)對(duì)應(yīng)的CPU指令集凶杖;對(duì)于Release Archive版本胁艰,需要選擇NO,這樣編譯出來(lái)的安裝包才能同時(shí)支持在armv7智蝠、arm64機(jī)型上安裝腾么。
Build Locations:配置構(gòu)建目錄,包括Intermediate Build Files Path杈湾、Build Products Path及其針對(duì)Per-Configuration的配置解虱。
Build Options:
Compiler for C/C++/Objective-C默認(rèn)時(shí)Apple LLVM 7.0;
Debug Information Format:真機(jī)連接調(diào)試時(shí)漆撞,可斷點(diǎn)定位跟蹤調(diào)試殴泰,可選擇DWARF以加快編譯速度于宙;但是真機(jī)斷開(kāi)Xcode運(yùn)行出現(xiàn)crash時(shí),沒(méi)有調(diào)試符號(hào)將無(wú)法逆向解析定位出問(wèn)題的代碼符號(hào)及其所在具體位置悍汛,故一般要選擇DWARF with dSYM File捞魁。
此外還包括Bitcode和Testability兩個(gè)使能開(kāi)關(guān)。
Code Signing:包括Entitlements离咐、Identity和Provisioning Profile谱俭,詳情參考《iOS Provisioning Profile(Certificate)與Code Signing詳解》。
Deployment:配置發(fā)布及安裝選項(xiàng)宵蛀。
Linking:
Dead Code Stripping:一般對(duì)Debug關(guān)閉昆著,對(duì)Release版本開(kāi)啟以去除無(wú)效路徑僵尸代碼,壓縮安裝包體積术陶。
Mangled Names(LINKER_DISPLAYS_MANGLED_NAMES):針對(duì)C++ symbols宣吱,ld --no-demangle鏈接開(kāi)關(guān),一般選擇NO瞳别。
Mach-O type:Static Library、Dynamic?Library杭攻、Executable祟敛、Bundle、Relocatable Object File(Position-Dependent )兆解。
Other Linker Flags:例如fobjc-arc(可在Build Rules中針對(duì)單個(gè)文件配置ARC開(kāi)關(guān))馆铁、-force_load。
Write Link Map File:寫(xiě)LinkMap文件锅睛。
Path to Link Map File:指定鏈接LinkMap文件路徑埠巨。
Packaging:
Info.plist File:指定plist文件,對(duì)應(yīng)頂部Info標(biāo)簽现拒。
Product Name:為應(yīng)用名稱(chēng)辣垒,例如QQ。
Wrapper Extension:為應(yīng)用擴(kuò)展印蔬,例如app勋桶。
Search Paths:
Info.plist File:指定plist文件,對(duì)應(yīng)頂部Info標(biāo)簽侥猬。
Framework Search Paths: *.framework搜索路徑例驹。
Header?Search Paths:*.h/*.hh頭文件搜索路徑。
Library??Search Paths:靜態(tài)庫(kù)退唠、動(dòng)態(tài)庫(kù)搜索路徑鹃锈。
Apple LLVM 7.0配置:
??Code Generation:
? ? Generate Debug Symbols:YES
? ? Optimization Level:優(yōu)化級(jí)別,-Os
??Custom Complier Flags:
??Language
? ? language-Objective-C:Objective-C Automatic Reference Counting瞧预,ARC開(kāi)關(guān)屎债。
??Preprocessing:定義Preprocessor Macros仅政,例如DEBUG、NDEBUG=1扔茅。
??Warning Policies:例如可以提高警告級(jí)別當(dāng)作錯(cuò)誤(Treat Warnings as Errors:YES)已旧。
Target Dependencies:設(shè)置依賴(lài)target。
Copy Bundle Resources:拷貝的資源文件召娜。
Compile Sources:該target需要編譯的源代碼文件运褪。可輸入搜索源代碼文件名(xxx.mm)玖瘸,查看或編輯其編譯選項(xiàng)(Compiler Flags)秸讹,例如 -fobjc-arc表示 ARC(__has_feature(objc_arc))。
Link Binary with Libraries:需要鏈接的庫(kù)(*.a雅倒、*.framework)璃诀。
Embed App Extensions:該APP對(duì)應(yīng)的擴(kuò)展插件。
可以點(diǎn)擊加號(hào)蔑匣,New Run Script Phase劣欢,配置custom actions after compiling the Xcode project,相當(dāng)于Visual Studio的Post-builtstep裁良。
當(dāng)然凿将,也可以在Edit Scheme中設(shè)置Pre-actions(custom actions after compiling the Xcode project)、Post-actions(將在編譯鏈接完成后執(zhí)行腳本)价脾。
以下Shell腳本將生成的二進(jìn)制(Unix executable)文件HelloWorld拷貝到~/Software牧抵,然后cd到該目錄下并執(zhí)行HelloWorld:
shift+command+K:清除products|debug或release下的Unix executable文件。
option+shift+command+K:刪除構(gòu)建目錄(Delete/Clean Build Folder)侨把,清理Derived Data對(duì)應(yīng)target目錄下的Build文件夾(包括intermediate和products)犀变。通常用于重新編譯整個(gè)工程,嘗試解決增量編譯時(shí)部分符號(hào)陳舊導(dǎo)致鏈接不通過(guò)的問(wèn)題秋柄。
Product -> Edit Scheme(option+command+R)->Info->Build Configuration:選擇生成版本(Debug or Release)
command + B:構(gòu)建(Buid)
command+8可聚焦左側(cè)導(dǎo)航欄中的日志報(bào)告導(dǎo)航器获枝,其中可以查看Build日志。
command+4可定位Issue Navigator:
當(dāng)編譯錯(cuò)誤(error)和警告(warning)過(guò)多時(shí)华匾,點(diǎn)擊底端的感嘆號(hào)映琳,即可忽略編譯警告,只顯示編譯錯(cuò)誤:
command + R:運(yùn)行(Run)蜘拉,可能會(huì)重新編譯鏈接萨西。
option+command + R:如果確定代碼沒(méi)有改動(dòng),加option鍵可免重新編譯鏈接旭旭,直接運(yùn)行上次build成功的product(Run Without Building)谎脯。
command + .:停止運(yùn)行(Stop)。
定義好Target構(gòu)建配置后持寄,接下來(lái)需要指定目標(biāo)機(jī)編譯源梭。
目標(biāo)機(jī)的iPhoneOS.platform必須>=Deployment Target娱俺,且Xcode必須支持該機(jī)型:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/目錄下必須含有對(duì)應(yīng)iOS系統(tǒng)版本的DeveloperDiskImage.dmg,否則真機(jī)編譯會(huì)提示Could not find developer disk image废麻。
shift+command+2:可以查看當(dāng)前連接的Device和支持的Simulator荠卷。
control+option+command+[/]:Select Previous/Next Destination,在連接多個(gè)真機(jī)或模擬器之間切換烛愧。
shift+command+Y:顯示控制臺(tái)(Show/Hide the debug area)
shift+command+C:激活聚焦控制臺(tái)油宜,光標(biāo)定位到控制臺(tái)呈可輸入狀態(tài)
command+K:清除控制臺(tái)(Debug->Debug Workflow->Clear Console)
可安裝BBUDebuggerTuckAway插件,在打字coding時(shí)怜姿,自動(dòng)隱藏調(diào)試控制臺(tái)
command + \:當(dāng)前行設(shè)置/取消斷點(diǎn)慎冤;通過(guò)鼠標(biāo)點(diǎn)擊邊列中的藍(lán)色斷點(diǎn)來(lái)啟用/禁用當(dāng)前行斷點(diǎn)。
command + Y:全局激活或禁用所有的斷點(diǎn)沧卢,激活進(jìn)入調(diào)試模式(此時(shí)斷點(diǎn)藍(lán)色可見(jiàn))蚁堤。
邊列(Gutter)中的斷點(diǎn)/警告可右鍵呼出Reveal in Breakpoint/Issue Navigator。
trick:編輯斷點(diǎn)(Edit Breakpoint):
Condition:設(shè)置斷點(diǎn)的觸發(fā)條件但狭,例如“i==3”(注意不能有空格)表示當(dāng)i等于3時(shí)該斷點(diǎn)才會(huì)被觸發(fā)披诗。
Ignore:設(shè)置斷點(diǎn)需要被忽略多少次才會(huì)中斷,若設(shè)置成5則表示第6次遇到該斷點(diǎn)時(shí)才觸發(fā)立磁。
Action:設(shè)置斷點(diǎn)觸發(fā)時(shí)的動(dòng)作藤巢,可以為Debugger Command、Log Message息罗、Shell Command或Sound。
例如可設(shè)置以下Debugger Command:
[1]讀取std::string sig的內(nèi)存buffer值:mem read sig.c_str() -c sig.size()才沧;
[2]打印NSData實(shí)例sig:po sig
F6:下一步(Step Over)迈喉,逐過(guò)程單步調(diào)試,不進(jìn)入函數(shù)體温圆。
(fn+)F7:進(jìn)入(Step Into)函數(shù)體挨摸。可能與多媒體鍵有沖突岁歉,故需要fn輔助(建議將功能鍵F1-F12設(shè)置為標(biāo)準(zhǔn)的功能鍵)得运。
(fn+)F8:跳出(Step Out)函數(shù)體」疲可能與多媒體鍵有沖突熔掺,例如呼叫iTunes,故需要fn輔助非剃。
control+command+Y:逐斷點(diǎn)繼續(xù)執(zhí)行(Pause/Continue)置逻。
control+command+C:執(zhí)行到當(dāng)前光標(biāo)所在行(Continue to current line)。
trick:移動(dòng)指令指針(Move the instruction pointer):
斷點(diǎn)調(diào)試運(yùn)行時(shí)备绽,可以將綠色指針箭頭(Line 47)移動(dòng)到其他行(Line 49)或其他斷點(diǎn)(Line 51)實(shí)現(xiàn)跳轉(zhuǎn)執(zhí)行券坞。
command+8可聚焦左側(cè)導(dǎo)航欄中的日志報(bào)告導(dǎo)航器鬓催,其中可以查看Debug日志。
shift+command+M:Debug Workflow->View Memory恨锚。
Debug Workflow->ShowDisassemblyWhen Debugging宇驾,可進(jìn)行匯編指令級(jí)調(diào)試。
trick:修改變量?jī)?nèi)存值(change?memory value while debugging):
調(diào)試運(yùn)行時(shí)猴伶,可以在底部的調(diào)試窗口(Debug Area课舍,可通過(guò)Shift+Command+Y呼出)右鍵某個(gè)變量,除了可以進(jìn)行View Memory/View Value As之外蜗顽,還可以選擇Edit Value運(yùn)行時(shí)編輯內(nèi)存變量的值布卡。
在調(diào)試驗(yàn)證某些難以復(fù)現(xiàn)的bug或進(jìn)行邊界測(cè)試時(shí)非常有用,可減少每次修改測(cè)量樣本值(hardcode)重新編譯鏈接的痛苦雇盖。
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(動(dòng)態(tài)執(zhí)行C/ObjC/C++表達(dá)式)脓鹃;
p/print/expr/expression:print as a?C/C++ basic variable逸尖;
// 打印SYSTEM_VERSION(可能要加UIDevice*轉(zhuǎn)換)
(lldb)p[[[UIDevicecurrentDevice]systemVersion] doubleValue]
po/expr-O/expression-O:Print as an Objective-C object;
// 打印屏幕bounds(可能要加UIScreen*轉(zhuǎn)換)
(lldb)poNSStringFromCGRect([[UIScreenmainScreen] bounds])
// 打印狀態(tài)欄frame(可能要加UIApplication*轉(zhuǎn)換)
(lldb)poNSStringFromCGRect([UIApplicationsharedApplication].statusBarFrame)
// 打印當(dāng)前keyWindow的根視圖(可能要加UIViewController*轉(zhuǎn)換)
(lldb)po[[[UIApplicationsharedApplication] keyWindow] rootViewController]
call:調(diào)用瘸右。其實(shí)上述p/po后接表達(dá)式(expression)也有調(diào)用的功能娇跟,一般只在不需要顯式輸出,或是無(wú)返回值時(shí)使用call太颤,用于動(dòng)態(tài)調(diào)試插入調(diào)用代碼苞俘。
例如可以在viewDidLoad:里面設(shè)置斷點(diǎn),然后在程序中斷的時(shí)候輸入以下命令:
// 調(diào)用后龄章,繼續(xù)運(yùn)行程序吃谣,view的背景色將變成紅色
(lldb)?call[self.viewsetBackgroundColor:[UIColorredColor]]
bt(backtrace),打印當(dāng)前調(diào)用堆棧(crash堆棧)做裙,“btall”可打印所有thread的堆棧(相當(dāng)于command+6的Debug Session Navigation)岗憋。
image:可用于尋址,有多個(gè)組合命令锚贱,比較實(shí)用的一種用法是尋找棧地址對(duì)應(yīng)的代碼(行)位置澜驮。
例如某個(gè)UITableView總共有2個(gè)section,當(dāng)其引用的currentSection.index≥2時(shí)將會(huì)引起[UITableView rectForHeaderInSection:]調(diào)用異常惋鸥,可使用expr動(dòng)態(tài)改值制造crash場(chǎng)景模擬調(diào)試杂穷。
此時(shí)crash時(shí)的控制臺(tái)bt顯示異常出現(xiàn)在應(yīng)用層代碼“0x00d055b8-[FACategoryTableView FACategorySectionHeaderDidTouched:] +744”處(其中0x00d055b8為當(dāng)前棧(代碼段)偏移量悍缠,744為棧幀偏移量——PC指針相對(duì)函數(shù)入口的偏移)。
那么具體是FACategoryTableView.m文件哪一行代碼調(diào)用引起的異常呢耐量?此時(shí)通過(guò)“image lookup --address”后接bt的call stack中的代碼段偏移地址(0x00d055b8)即可定位出異常調(diào)用的代碼行位置飞蚓。
x/memoryread:dump指定地址的內(nèi)存(Read from the memory of the process being debugged),后接起止地址或-c指定count加起始地址廊蜒∨颗。可help mem read查看幫助:
Syntax:
memory read []
Command Options Usage:
size指定內(nèi)存塊(block/chunk)的大小
? ? --size ):The size in bytes to use when displaying with the selected format.
count指定內(nèi)存塊(block/item)的個(gè)數(shù),可配合起始地址使用山叮。
? ? -c ( --count ):The number of total items to display.
format指定內(nèi)容顯示格式著榴,格式符同print:c-char,s-string屁倔,d-decimal脑又,x-hex。
? ? -f ( --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的字節(jié)數(shù),以上等效:
(lldb)mem read 0x10b88f0c -c 9
0x10b88f0c: 39 38 37 36 35 34 33 32 31 ? ? ? ? ? ? ? ? ? ? ? 987654321
(c)起始地址+內(nèi)存塊size+內(nèi)存塊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
說(shuō)明:dump的memory chunk為1byte钞翔,以上總共dump了chunk size*chunk count=9byte严卖。
(d)起始地址+內(nèi)存塊size+內(nèi)存塊count(dump char format)
(lldb)memory read -s 1 -f c -c 9 0x10b88f0c
0x10b88f0c: 987654321
(e)起始地址+內(nèi)存塊size+內(nèi)存塊count(dump string format)
(lldb)mem read 0x10b5cf2c -f s -c 1
0x10b88f0c: "987654321"
(f)起始地址+內(nèi)存塊size+內(nèi)存塊count(dump int format)
(lldb)memory read -s 4 -f x -c 3 0x10b88f0c
0x10b88f0c: 0x36373839 0x32333435 0x109f0031
說(shuō)明:以上指定chunk尺寸為4byte(-s ?4),chunk數(shù)量為3布轿,共dump了12個(gè)byte哮笆。
memory?write:改寫(xiě)指定地址的內(nèi)存(Write to the memory of the process being debugged)√ぃ可自行help mem write查看幫助:
Syntax: memory write [ [...]]
trick:lldb打印無(wú)效問(wèn)題
在使用LLDB調(diào)試命令p/po打印C類(lèi)型(包括復(fù)合類(lèi)型)或Objective-C對(duì)象時(shí)疟呐,可能會(huì)遇到屬性不存在或類(lèi)型不匹配的問(wèn)題。
例1——斷點(diǎn)調(diào)試东且,打印當(dāng)前UIViewController的frame:
由于Xcode lldb本身的bug,對(duì)屬性的點(diǎn)引用有時(shí)會(huì)無(wú)法識(shí)別本讥,例如執(zhí)行(lldb)?p self.view.frame報(bào)錯(cuò):property 'frame' not found on object of type 'UIView *'
將對(duì)屬性的點(diǎn)引用改為對(duì)屬性的getter調(diào)用珊泳,執(zhí)行(lldb)?p [self.view frame]依舊報(bào)錯(cuò):no known method '-frame'; cast the message send to the method's return type
由于Xcode lldb本身的bug,對(duì)返回的復(fù)合類(lèi)型也無(wú)法直接識(shí)別拷沸,此時(shí)可采用顯示類(lèi)型轉(zhuǎn)換色查,執(zhí)行(lldb)?p (CGRect)[self.view frame]不會(huì)報(bào)錯(cuò)!
例2——斷點(diǎn)調(diào)試撞芍,打印當(dāng)前UIViewController的navigationController堆棧和childViewControllers數(shù)組:
點(diǎn)引用報(bào)錯(cuò)寫(xiě)法(property not found):(lldb)po self.navigationController.viewControllers
調(diào)用getter正確打友砹恕:(lldb)po [[self navigationController] viewControllers]
點(diǎn)引用報(bào)錯(cuò)寫(xiě)法(property not found):(lldb)?po self.childViewControllers
調(diào)用getter正確打印:(lldb)po [self childViewControllers]
(6)啟用NSZombieEnabled調(diào)試EXC_BAD_ACCESS
當(dāng)你對(duì)已釋放的對(duì)象發(fā)送消息(90%的可能是對(duì)引用計(jì)數(shù)為0的對(duì)象再release)或release那些autorelease對(duì)象時(shí)序无,就會(huì)出現(xiàn)報(bào)EXC_BAD_ACCESS這樣的錯(cuò)誤验毡。
默認(rèn)設(shè)置下 Xcode不會(huì)給你定位具體是哪一行代碼不該去使用已釋放的對(duì)象衡创,或者release用錯(cuò)了。
Product -> Edit Scheme(option+command+R)?-> Diagnostics晶通,勾選“Objective-C”之后的“Enable Zombie Objects”璃氢。
設(shè)置NSZombieEnabled環(huán)境變量后,一個(gè)對(duì)象銷(xiāo)毀時(shí)會(huì)被轉(zhuǎn)化為_(kāi)NSZombie狮辽;設(shè)置NSZombieEnabled后一也,當(dāng)你向一個(gè)已經(jīng)釋放的對(duì)象發(fā)送消息,這個(gè)對(duì)象就不只是報(bào)EXC_BAD_ACCESS Crash喉脖,還會(huì)放出一個(gè)錯(cuò)誤消息椰苟,然后以一種可預(yù)測(cè)的可以產(chǎn)生debug斷點(diǎn)的方式消失, 因此我們可以找到具體或者大概是哪個(gè)對(duì)象被錯(cuò)誤的釋放或引用了树叽。
注意:NSZombieEnabled只能在調(diào)試的時(shí)候使用舆蝴,千萬(wàn)不要忘記在產(chǎn)品發(fā)布的時(shí)候去掉,因?yàn)镹SZombieEnabled不會(huì)真正去釋放dealloc對(duì)象的內(nèi)存菱皆,一直開(kāi)啟后果自負(fù)!
參考
《Xcode Overview-About Xcode》《Xcode Keyboard Shortcuts and Gestures》
《Xcode Key Bindings & Gestures》《提升Xcode效率的小技巧》
《用Vim編輯器輔助Xcode》《Vim命令圖解和xVim使用》《升級(jí)Xcode7后XVim插件失效的修復(fù)辦法》
《Xcode的文件組織》《Xcode設(shè)置命令行啟動(dòng)參數(shù)》
《Xcode環(huán)境變量及路徑設(shè)置》《Xcode構(gòu)建輸出目錄》
《從VC到Xcode》《workspace & subProject & target》
《Xcode創(chuàng)建靜態(tài)庫(kù)》《Xcode4制作靜態(tài)庫(kù)1》《Xcode4制作靜態(tài)庫(kù)2》
《Xcode4.3下制作framework》《Xcode添加依賴(lài)的靜態(tài)庫(kù)工程》
《Building static libraries with the iPhone SDK》《Static Libraries and Cross-Project References》
《iOS開(kāi)發(fā)之統(tǒng)計(jì)Xcode代碼行數(shù)》《Start Developing iOS Apps Today》
《使用Xcode創(chuàng)建Hello World項(xiàng)目》《使用Xcode5和Interface Builder創(chuàng)建Hello World App》
《LLDB Quick Start Guide》《LLDB to GDB Command Map》《Xcode gdb/lldb調(diào)試命令》
《Xcode LLDB Debug教程》《LLDB調(diào)試命令初探》《iOS應(yīng)用崩潰日志揭秘》《經(jīng)營(yíng)你的iOS應(yīng)用日志》
《讓lldb提升你的效率》《iOS/OSX 調(diào)試:跳舞吧篷店!與LLDB共舞華爾茲》《NSLog效率低下的原因及嘗試lldb斷點(diǎn)打印Log》