Xcode操作流

2023-05-16

 

1.Xcode IDE概览

说明:从左到右,依次是“导航窗格(Navigator)->边列(Gutter)->焦点列(Ribbon)->代码编辑窗口(Standard/Primary Editor)”。

  • 边列(Gutter:显示行号和断点。
  • 焦点列(Ribbon):灰色深度与代码嵌套深度相关:鼠标悬停可突出显示右侧相应代码块(Focus code blocks on hover),鼠标单击可折叠右侧相应代码块(Code folding)。

2.偏好设置

通过 “command+,” 快捷键或 ”Xcode|Preferences” 菜单可呼出偏好设置。

(1)主题及字体(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 可更改字体(大小)。

(2)编辑器配置(Preferences->Text Editing)

Editing

  • Show Line Numbers:在gutter中显示行号。
  • Code folding ribbon:显示焦点列。

    Focus code blocks on hover:鼠标悬停时突出显示右侧相应代码块。

  • Page guide at column:显示一行最多支持80个字符的提示分割线。
Indentation
  • Prefer indent using:Spaces(为保持一致的视觉呈现和行末注释对齐,建议使用空格)
  • Tab width:4 spaces(tab expand,1个tab=4个空格)
  • Indent width:4 spaces(自动缩进步长=4个空格)

(3)跳转打开方式(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+双击)时,新建标签页。

(4)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)。

(5)SDK/Simulator(Preferences->Downloads)

Downloads:可下载Components(SDK&Simulator)和Documentation。

(6)构建输出目录(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)。

option+双击:打开选中符号的帮助文档。

(2)View Navigator

option+command+T:Show/Hide Toolbar

command+0:Show/Hide left tool panel(Navigator Area)

command+1-8:Project/Source Control/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

再按下 ⌥⌘T 隐藏顶部工具栏,再按下 0 / ⌥⌘0 隐藏左右侧边栏,聚焦中间的编辑区(Standard/Primary Editor),有效利用屏幕编码。

(3)View Editor Organization

control+1:Show Related Items(例如 Superclasses/SubclassesCallers/CalleesProtocol 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 List),支持即时搜,非常实用。

(4)Eidtor Window/Tab Switch

command+shift+[/]:切换标签页

单/双指左右滑动(control+command+←/→):在单标签页打开的多个文件间切换(Go Back/Forward)

(5)Symbol Jump

command+L跳转到指定行。

shift+command+O:Open Quickly,快速全局查找文件、符号,高频实用!

command+click:点击跳转到光标所在的符号定义(jump to definition)。

control+command+J:跳转到指定符号的定义处或实现处(Go to Declaration/Definition)。有时工程正在Loading、Indexing或Processing files时,“command+点击”无法响应,此时可试试 control+command+J

control+command+↑/↓:切换头文件/实现文件(switch between a source file (.m,*.mm,*.cc) and the associated header file(.h),Jump to Previous/Next Counterpart)。

在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),过滤显示包含该单词的符号。

注意^6 只列出当前文件代码中的符号,而 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+`:Move Focus 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

esccontrol+.)就当前输入上下文呼出/隐藏智能提示列表(Auto Completion List);

上下方向键↑/↓)在智能提示列表中选择选项。当然,也可以用control+.;enter 选中列表中备选的消息符号;

tab 在輸入符号不完整时可一截一截匹配;选中消息符号后,tab 可在各个参数占位符之间移动enter 可选中参数占位符先临时补位填充。

输入Objective-C对象及消息名,然后输入 ],自动补充对象名左侧的,完成中缀符(infix natation)包围。

(4)Find菜单(control+单击)

当鼠标定位或选中某个符号时,可呼叫 右键快捷菜单
  • Find Selected Text in Workspace:在当前工作空间查找选中文本或光标所在行的OC冒号分割方法名。
  • Find Selected Symbol in Workspace(control+shift+command+F):在当前工作空间查找选中文本符号或光标所在行的OC冒号分割方法符号。
  • Find Call Hierarchy(control+shift+command+H:查找符号或光标所在行的OC冒号分割方法符号的调用者(Callers)。

说明^1|Callers 只能看到一级调用者,Find Call Hierarchy 可向上追溯更高层级的调用者。

(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键可实现竖直块选;调节音量/亮度时,按住optionshift 可以四分之一单位微调

使用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+command+J:在辅助编辑窗口中打开指定符号的定义处或实现处(Go to Declaration/Definition)。
  • option+control+command+↑/↓在辅助编辑窗口中打开对应的头文件(*.h)/实现文件(*.m,*.mm,*.cc)。

点击查看 shift+command+Oshift+command+F(command+3)选中的文件或符号时,可同时按下option在辅助编辑窗口中打开。在control+1~6中打开选择结果时,均可同时按下option在辅助编辑窗口中打开。

(3)导航窗格(option+shift+)

在Xcode以上种种切换跳转操作时,按下option的同时按下shift,通常会呼出一个导航窗格(option+command+<),可选择在new window/tab/assistant-editor打开显示。

 

For Option-Shift navigation (Option-Shift-click or Option-Shift-choose a file), Xcode displays a graphical navigation chooser showing the current layout. The chooser prompts you to open the file in any open editor pane in any window and tab, or to open the file in a new editor pane, window, or tab.

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了所有的环境变量。

> 关于 xcodebuild 参考《了解 xcodebuild 命令》、《iOS 自动构建命令——xcodebuild》;

(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 Schemeoption+command+R)->Arguments->Environment Variables中可以添加自定义环境变量(Name为名称,Value为值)。

在Xcode|Build Phases中Add Run Script Build Phase的Run Script将会使用到环境变量。

7.构建配置

关于 iOS 工具链编译链接原理,可参考《浅谈 Xcode 编译过程》、《iOS 编译过程的原理和应用》和《深入剖析 iOS 编译 Clang / LLVM》。

(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 Schemeoption+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构建配置后,接下来需要指定目标机编译。

 

shift+command+2:可以查看当前连接的Device和支持的Simulator。

control+option+command+[/]:Select Previous/Next Destination,在连接多个真机或模拟器之间切换。

 

目标机的iPhoneOS.platform必须>=Deployment Target,且Xcode必须支持该机型:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/目录下必须含有对应iOS系统版本的DeveloperDiskImage.dmg,否则真机编译会提示Could not find developer disk image。

 

最新的 Xcode 8 最低支持 iOS 8.0,如果连接的设备运行 iOS 7 则无法编译,则提示:

Could not locate device support files.《This iPhone 5 (Model A1429) is running iOS 7.0.4 (11B554a), which may not be supported by this version of Xcode.》
可以将 Xcode 7 中的 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport 中的 7.0、7.1 的 DeveloperDiskImage(DeveloperDiskImage.dmg & DeveloperDiskImage.dmg.signature)拷贝到 Xcode 8 对应目录,然后在项目配置 General | Deployment Info | Deployment Target 硬性填写 7.0,即可 在 Xcode 8 中调试 iOS 7 真机设备。

XCode 8.0 解决没有 iPhone 4s 模拟器问题 的方法。

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 [[[UIDevicecurrentDevicesystemVersion] 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 Schemeoption+command+R -> Diagnostics ,勾选“Objective-C”之后的“Enable Zombie Objects”。
设置NSZombieEnabled环境变量后,一个对象销毁时会被转化为_NSZombie;设置NSZombieEnabled后,当你向一个已经释放的对象发送消息,这个对象就不只是报EXC_BAD_ACCESS Crash,还会放出一个错误消息,然后以一种可预测的可以产生debug断点的方式消失, 因此我们可以找到具体或者大概是哪个对象被错误的释放或引用了。
注意:NSZombieEnabled只能在调试的时候使用,千万不要忘记在产品发布的时候去掉,因为NSZombieEnabled不会真正去释放dealloc对象的内存,一直开启后果自负!

 

参考

《Xcode Overview-About Xcode》《Xcode Keyboard Shortcuts and Gestures》

《Xcode Key Bindings & Gestures》《提升Xcode效率的小技巧》

《Xcode5.1离线安装》《Xcode插件》

《用Vim编辑器辅助Xcode》《Vim命令图解和xVim使用》《升级Xcode7后XVim插件失效的修复办法》

 

《Xcode的文件组织》《Xcode设置命令行启动参数》

《Xcode环境变量及路径设置》《Xcode构建输出目录》

从VC到Xcode》《workspace & subProject & target

 

《Xcode创建静态库》《Xcode4制作静态库  1》《Xcode4制作静态库 2》

《Xcode4.3下制作framework》《Xcode添加依赖的静态库工程》

《Building static libraries with the iPhone SDK》《Static Libraries and Cross-Project References》

 

《iOS开发之统计Xcode代码行数》《Start Developing iOS Apps Today

《使用Xcode创建Hello World项目》《使用Xcode5和Interface Builder创建Hello World App》

 

《LLDB Quick Start Guide》《LLDB to GDB Command Map》《Xcode gdb/lldb调试命令》

《Xcode LLDB Debug教程》《LLDB调试命令初探》《iOS应用崩溃日志揭秘》《经营你的iOS应用日志》

《让lldb提升你的效率》《iOS/OSX 调试:跳舞吧!与LLDB共舞华尔兹》《NSLog效率低下的原因及尝试lldb断点打印Log》

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Xcode操作流 的相关文章

  • 配置文件与应用程序标识符不匹配

    我刚刚为应用程序 ID 49776ZQRBG com gfeed ride 创建了一个 AdHoc 分发配置文件 我在 info plist 中将 Bundle ID 设置为此 但项目设置中的此配置文件显示为灰色并显示 配置文件与应用程序标
  • 在 macOS 中获取用户首选的温度设置

    我正在尝试读取温度单位 摄氏度 华氏度 的用户设置系统首选项 我试图使用 NSLocale 获取此数据 但我找不到任何温度设置的证据 甚至可以读取这些数据吗 Thanks 官方 API 记录在首选项 实用程序 https developer
  • XCode iPhone 项目中目标所有配置的通用预处理器宏

    我的应用程序的每个目标通常有四种配置 调试 发布 分发 临时 有没有办法为所有 4 个添加一个通用宏 同时不破坏我到目前为止设置的宏 您在编辑器中看到 多个值 提前致谢 奥比旺 在前缀头文件中定义宏 将包含在所有源文件中
  • Swift - 集成 GameCenter 以使用排行榜

    我正在用 Swift 制作一个游戏 我希望能够使用 GameCenter 发布用户的分数 以便可以看到所有用户的分数 然而 我花了一天的时间试图弄清楚如何做到这一点 但我没有找到任何有用的说明 我对 iOS 编程和 Swift 还很陌生 关
  • 更新 OSX 命令行工具 6.3 后缺少 C++ 标头 <__debug>

    从 App Store 更新到 Command Line Tools 6 3 后 程序包括
  • NSRunningApplication - 终止

    我将如何使用NSRunningApplication 我有与启动应用程序相反的东西 NSWorkspace sharedWorkspace launchApplication appName 但我想关闭一个 当我调试代码时出现错误NSRun
  • 无法将类型“X”的值转换为预期参数类型“X”

    Xcode 8 和 Swift 3 今天让我非常难过 请看一下并告诉我您是否遇到过类似的问题以及是否可以解决它 我一直在尝试不同的解决方案 其中 Cmd Shift K Cmd Shift Option K 删除派生数据 更改使用的结构 它
  • 越狱后,iOS应用程序会以root权限运行吗?

    一旦 iOS 设备越狱 我们就可以构建越狱应用程序 使用 theos 并将其安装在 Applications预加载应用程序以 root 权限运行的目录 如果应用程序是使用 Xcode 构建的 一旦安装 它就会进入 private var m
  • MacOSX 下 libpng 的链接器错误

    我正在使用 MacOSX 10 7 2 和 Xcode 4 2 1 我安装了libpng使用端口 我试图在我的应用程序中加载 PNG 图像 但出现链接器错误 Undefined symbols for architecture x86 64
  • 如何在 XCode 中将 C++ 与 Objective-C 结合使用

    我想在 Objective C 中使用 重用 C 对象 我有一个包含类定义的 hello h 和用于类实现的 hello cpp class Hello int getX 我在 Objective C 函数中使用这个类 include he
  • 如何将 UIImage 和 UILabel 合并为一张图像并保存

    我有 2 个 UILabels 和 2 个图像 我需要将它们合并到一个 UIImage 中进行保存 我知道我可以用屏幕截图来做到这一点 但我的主图像是圆形的 所以如果我对其进行校正 它仍然会显示锐利的边缘 我可以这样做来组合图像 CGSiz
  • 在 MAC OSX 上使用 CMake 生成 .bundle 文件

    我想生成一个可执行文件 bundle文件于Mac OSX 10 6 8 using CMake 我的 CMakeLists txt 文件如下所示 cmake minimum required VERSION 2 8 PROJECT TEST
  • iOS 获取特定语言的字符串的本地化版本

    我正在构建一个适用于 iOS 的应用程序 该应用程序将提供英语和法语版本 我已经阅读了一些有关国际化的教程 并且了解了它的工作原理以及我需要做什么 我遇到的问题是有一个特定的情况 我想为英语用户加载法语字符串 我知道可以为整个应用程序设置语
  • iPhone en_* 子语言本地化

    我想在我的 iphone 应用程序中将字符串本地化为 en GB 和其他 en 子语言 但 XCode 和 iphone 拒绝让这种情况发生 我已经为 en GB 和 en US 创建了 Localized strings 的本地化 我尝试
  • [UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]

    我正在使用表格视图来显示消息 我使用了下面的代码 UIView chatView self bubbleView NSString stringWithFormat message from YES self chatArray addOb
  • 如何在 Xcode 中自动增加内部版本号 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在这个网站上找到了很多解决方案和脚本 但在 Xcode 中增加构建号的最简单的解决方案是 转到 TARGETS 部分中的 Build P
  • 如何从 Xcode 4.5 卸载 iOS 5.0 模拟器

    我已经安装了 Xcode 4 5 由于我编写应用程序是为了好玩 我不打算支持旧版 iOS 版本 并且为了节省 500 GB iMac 上的空间 是否有办法删除它 尝试从 Xcode 包中支持的平台中删除 iPhone iPhoneSimul
  • 如何将 NSMutableArray 添加到 NSMutableArray Objective-c

    我正在从 Java 切换到 Objective c 但遇到了一些困难 我已经搜索过这个问题但没有取得太大成功 我有一个存储 NSMutableArrays 的 NSMutableArray 如何向数组添加数组 您可以在数组中存储对另一个数组
  • Xcode11 编辑器(通过“将编辑器添加到右侧”)被禁用

    自从我升级到以来它一直在工作Xcode11 2 几天前注意到了它 现在它不允许我向布局添加编辑器 如同Xcode 11 中引入的编辑器更改 https www avanderlee com xcode xcode assistant edi
  • TestFlight 安装的应用程序因 Swift 包管理器依赖项而崩溃

    我们已经迁移了一些 CocoaPod 依赖项 以便在 Xcode 11 中使用 Swift Package Manager 进行构建和链接 但是 每当我们将应用程序提交到 AppStore Connect 并使用 TestFlight 进行

随机推荐

  • C++判断是否是IP地址

    判断是否是IP地址 bool isIPAddress const char s const char pChar bool rv 61 true int tmp1 tmp2 tmp3 tmp4 i while 1 i 61 sscanf s
  • C++判断是否是纯数字

    C 43 43 判断是否是纯数字 bool isDigitStr const char cstr if NULL 61 61 cstr cstr 0 61 61 0 return false int len 61 strlen cstr i
  • 命里有时终须有,命里无时莫强求

    命里有时终须有 xff0c 命里无时莫强求 今天是2012年2月24号 xff0c 和我谈了3个多月的女生突然之间说我们之间不合适 xff0c 让我以后不要再去骚扰她 真心第一次体会到失恋的感觉 xff0c 同时打电话给我姐姐诉说了下 xf
  • 共享内存--函数

    共享内存允许两个不相关的进程访问同一个逻辑内存 共享内存是在两个正在运行的进程之间传递数据的一种非常有效的方式 大多数的共享内存的具体实现 xff0c 都把由不同进程之间共享的内存安排为同一段物理内存 共享内存是由IPC为进程创建的一个特殊
  • GNOME 3 介绍 技巧

    https wiki archlinux org index php GNOME 28 E7 AE 80 E4 BD 93 E4 B8 AD E6 96 87 29 GNOME项目使用最新的科技 xff0c 为用户从头打造了全新的现代桌面
  • assert用法

    判断是否为真 include 34 stdio h 34 include lt string h gt include lt stdlib h gt define NDEBUG include lt assert h gt void mai
  • strcpy原型

    已知strcpy 函数的原型是 char strcpy char strDest const char strSrc 其中strDest 是目的字符串 xff0c strSrc 是源字符串 xff08 1 xff09 不调用C 43 43
  • new与delete正确用法

    说明 xff1a 推荐使用如下宏 xff0c 可以在一定程度上避免使用空指针 xff0c 野指针的问题 define HW NEW var classname do try var 61 new classname catch var 61
  • VNC启动gnome或者KDE

    VNC xstartup程序中默认的设定值可以启动twm xff0c 而不是GNOME或KDE 默认配置文件为 HOME vnc xstartup HOME 是用户目录 如下 gnome桌面的配置文件如下 xff1a bin sh Unco
  • crontab执行java -jar不成功

    一个程序经常挂掉 xff0c 不想人为的一种手动重启 故写了一个脚本 xff0c 定时查看程序是否存在 xff0c 不存在就重启 但是过程中一直crontab 设置的定时器一直不执行 crontab e 1 opt speak start
  • crontab 解决周期内未执行完重复执行

    crontab 解决周期内未执行完重复执行 crontabphplock crontab 执行 php 脚本 linux 下的 crontab 定时任务服务 xff0c 可以用来定时运行脚本 工作中经常会用到这样的服务 xff0c 使用起来
  • Kali Linux 2020 VNC设置自动开机启动

    前提 大家好 目前最新版kali Linux 2020离线包貌似已经取消了桌面安装了 xff0c 需要自己去手动安装桌面 xff0c 所以如果你还是命令行 xff0c 那你就先安装个桌面再说 xff0c 怎么装自己去百度 VNC安装过程 首
  • http://wwwnno00.irrlicht3d.cn:8011/forum-20-3.html

    http wwwnno00 irrlicht3d cn 8011 forum 20 3 html
  • git guest reporter

    权限列表如下 xff1a ActionGuestReporterDeveloperMasterOwnerCreate new issue Leave comments Pull project code Download project C
  • 元素化学期末(考点)整理

    元素化学 期末 xff08 考点 xff09 整理 作者 xff1a gjq 转载或引用需联系作者 xff0c 欢迎给作者打钱 xff01 2019年期末考题请联系作者 xff0c 作者微信 xff1a photon gjq xff0c q
  • 关于ubuntu自启动(rc.local,/etc/rcx.d软连接,创建自定义service)

    ubuntu自启动 xff08 总结 xff09 前言方法一 xff1a 编辑etc rc local方法二 xff1a rcx d 下添加脚本方法三 xff1a 创建service 前言 日常工作中难免碰到需要让某些应用程序自启动的功能
  • springMVC+mybatis环境搭建

    web xml文件配置 lt 加载Spring容器配置 gt lt 设置Spring容器加载所有的配置文件的路径 gt lt context param gt lt param name gt contextConfigLocation l
  • 解决 https 无法访问

    本人腾讯云服务器 xff0c 放假上班打开宝塔面板 xff0c 结果无法访问 我想着重启实例 xff0c 结果面板可以打开 xff0c 但是域名打不开了 xff08 之前是可以打开的 xff09 最后在这个地址找到了答案 xff0c 记录一
  • Python程序设计 简单的图像处理(1)

    Python程序设计 简单的图像处理 xff08 1 xff09 1 写个滤镜 照片照的好 xff0c 不如滤镜用得好 xff01 一款好的滤镜软件可以让照片呈现不一样的风格乃至风情 xff0c 修理照片需要扬长避短达到最佳效果 可是滤镜款
  • Xcode操作流

    1 Xcode IDE概览 说明 xff1a 从左到右 xff0c 依次是 导航窗格 xff08 Navigator xff09 gt 边列 xff08 Gutter xff09 gt 焦点列 xff08 Ribbon xff09 gt 代