OC基础回顾(六)了解和使用Xcode

来源:互联网 发布:响应式网站整站源码 编辑:程序博客网 时间:2024/05/21 16:56

1.了解IDE窗口

(1)窗口布局一览

窗口包括:工具栏,导航器面板,编辑器面板,调试器面板,检查器面板和库面板。
可以按住Command键+一个数字键(从1到7)或点击导航器面板的顶端的图标来切换导航器面板的视图。



在窗口的右上角有一组工具栏按钮




(2)更改公司名称的方法

新建Objective-C源文件时,Xcode会自动帮你生成注释文字。如下:
////  ViewController.h//  LearnXcode////  Created by SharonHu on 15/7/14.//  Copyright (c) 2015年Sharon. All rights reserved.//


Xcode在注释块中生成了文件名称、项目名称以及创建者和创建日期。
我们可以自己更改公司名称。
方法是:在导航器面板选中项目,在检查器面板的Project Document栏目下的Organization文本框中输入你的公司名称,在Class Prefix文本框中可以输入文件的前缀。如下图所示:



(3)一些使用技巧

A.过滤列表文件

使用导航器面板底部的搜索框可以过滤源列表文件,例如下图搜索出了名称中带有guide的文件。你可以在任意的导航器视图中使用这个搜索框。




B.窗口显示文件:
双击导航器面板中的某一个文件,可以用独立的全屏窗口显示这个源文件,这在比较两个不同文件时很有用。也可以用两个不同的窗口显示同一个文件,但是要注意有时候这两个窗口的内容会出现不同步的情况,因此需要点击其中某个窗口来使他们同步。

C.标签显示文件:
也可以用标签的显示方式(就像Safari一样)。显示标签的方法:View →Show Tab Bar选项,如下图:




2.Xcode偏好设置

通过“Command+逗号”快捷键或”Xcode|Preferences”菜单呼出偏好设置。

(1)主题及字体(Preferences->Fonts & Colors)

选中一种主题(theme),例如“Midnight”,然后shift选择Source Editor/Console中的所有项,点击Fonts设置字体。Xcode默认字体为menlo,可选Consolas、Monaco等其他等宽字体。

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

Editing:

  • Show Line Numbers:在编辑面板中显示行号。
  • Code folding ribbon:显示折叠ribbon。
  • 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)SCM(Preferences->Source Control)

Enable Source Control:启用/禁用XCode自带Source Control Manager(SCM)。

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

Downloads->Components:可下载SDK和Simulator。

(5)构建输出目录(Preferences->Locations->Locations)

  • 当选择为Default时,Derived Data的目录为~/Library/Developer/Xcode/DerivedData。
  • 当选择为Relative时,Derived Data的目录为当前.xcodeproj所在的目录。
  • 当选择为Custom时,Derived Data的目录需自定义。
    不建议使用绝对路径,因为写死之后,换环境或换平台,又要重新修改路径,建议使用相对路径(Relative

3. 在Xcode的帮助下编写代码

(1)首行缩进(美观排版)

选中文本后,按住Control键点击(或直接右击),在弹出来的上下文菜单中选择Structure → Re-Indent选项,Xcode会将代码重新排版。
快捷键Control + i 可以达到同样的效果。




通过Structure菜单,或者按下Command+ 【 键和 Command + 】键可以将选定的代码进行左移或者右移。

Xcode →Preferences → Text Editing → Indentation , 自定义Xcode内的代码风格。

(2)代码自动完成

编写程序时,Xcode会为所有内容生成索引,包括项目中的比变量名和方法名以及导入的框架。当输入代码时,Xcode会不断地比较你输入的代码和它生成的符号索引,如果匹配,Xcode就会给出建议。下图是我输入N时出现的自动完成列表:

E:枚举符号
f:表示函数
#:表示#define 指令
m:表示方法
C:表示类
等等

(3)批量编辑

   创建快照 :选择File  → Create Snapshot 选项(或者 Command + Control + S 快捷键)(如下图),Xcode会记住项目目前的状态,然后就可以随便编辑源文件而不用担心把项目“玩坏了”。




     如果意识到自己犯了一个严重的错误,可以通过File → RestoreSnapshot选项,打开快照窗口,这样就可以选择一个快照恢复项目了。如下图:


说明:快照文件存储在~Library/Developer/Xcode/Snapshots/目录中。


(4)查找替换功能

在导航器面板中选择搜索选项,或者快捷键Command + Shift + F,就可以对整个项目中的所有文件进行内容搜索和替换。可以点击Replace All对整个项目应用这个替换。


(5)重命名某一个符号的名称

选中一个符号,如局部变量或者参数,然后点击它,出现一个向下的箭头:


点击这个箭头,出现一个菜单,选择Edit all in Scope选项。


你会发现文件中所有使用了这个符号名称的地方都出现了一个虚线框,这时,在任意一个虚线框里修改符号名称,其他虚线框里的符号也会同时被修改。这个功能太棒了!只要单击编辑面板中的其他地方,就能退出Edit all in Scope模式了。


注意,如果发现Edit all in Scope菜单被禁用,这是因为这个功能与Xcode中的语法着色功能密切相关,如果你对语法着色功能改动过多或者关闭了它,Edit all in Scope功能也就停止工作。要解决这个问题,需要回到设置菜单,对语法着色功能进行调整,直到他能恢复工作。

(6)通过Xcode内置的重构工具修改类的名字
把光标放在类名上,右击,出现一个菜单列表,选择Refactor → Rename


在弹出的对话框中输入替代的类名:


可以点击Preview按钮,查看将要修改的地方:


确定修改没有问题后就点击Save。如果是第一次在项目中重构代码,Xcode会询问你是否要启用自动快照备份,选择yes是一个明智的决定。
注意:重构并不能重命名注释中的文字。可以用查找替换功能简化这一操作。


4.代码导航

在代码的生命周期中浏览代码的不同方法。

(1)emacs快捷键组合

指的是一些不用把手从键盘上拿开就能在文字中移动光标的快捷键。
emacs是一个很早就有的文本编辑器,它诞生在20世纪70年代,可以在现代的Mac操作系统上运行。

下面是这些按键及其功能:
Control-F :光标前(Forward)移效果(效果同右方向键
Control-B:光标后(Backward)退(效果同左方向键
Control-P:光标移动到上(Previous)一行(效果同上方向键
Control-N:光标移动到下(Next)一行(效果同下方向键
Control-A:光标移动到行首位置(效果同Command + 左方向键
Control-E:光标移动到行末位置(效果同Command + 右方向键
Control-T:交换(Transpose)光标两边的字符
Control-D:删除(Delete)光标右边的字符
Control-K:把当前光标以后的所有字符全部删除(Kill),便于重写行尾的代码。
Control-L:将光标置于窗口的正中央。如果你找不到光标的位置或者想要移动窗口使光标快速移动到正中央,这个快捷键会非常好用。

(2)快速打开的窍门

窍门一:快速查找并打开一个文件
File → Open Quickly(或者快捷键Shift + Command + O





打开了一个对话框,在搜索框中搜索关键词,就可以查找与这个关键词有关的文件:




诀窍二:同时显示头文件和它对应的实现文件
View → Assistant → Show Assistant Editor(或者快捷键 Option + Command + 回车键)。默认情况下如果一个面板显示的是头文件,那么另一个面板显示的就一定是实现文件,不过可以根据自己的喜好更改这一设定。点击工具栏的Counterparts菜单,就可以看到其他选项。





(3)代码折叠(code folding)

紧挨着源代码左侧有两个空栏:分别是边栏聚焦栏


注意聚焦栏的灰度,代码嵌套的越深,它的灰度就越深。这中颜色编码能够使代码的复杂程度一目了然。
在不同灰色区域悬停鼠标可以高亮显示响应的代码片段



(4)编辑面板上方的导航条

点击菜单按钮,可以看到快速打开最近访问的历史文件或执行其他高级的操作。
点击前进后退按钮,可以打开曾经编辑过的文件
功能菜单显示当前光标所在的方法,点击功能菜单可以看到文件中所有的符号。如下图所示:


蓝色高亮的地方,说明光标当前位于-tableView:heightForHeaderInSection:这个方法中。
按住Command键,并且点击功能菜单,就可以将文件中的方法按照字母顺序排列,如下图:


可以向菜单中加入其他内容。
有两种方法:一是使用#pragma mark whatever, 后面的whatever可以填写任何的文字,它会出现在菜单中。
#pragma -(减号),会在菜单中插入分割线。Xcode也会在注释里查看那些诸如“MARK:”(与#pragma mark 的功能相同)、“TODO”、“FIXME”、
“ !!!:”和“ ??? :”之类符号开头的文本,并将这些文本放入功能菜单中。最程序发布之前,最好先看看这些标记。


5.获取信息

(1)获得帮助

检查器面板顶端有两个图标
点击第一个图标,检查器显示的是当前文件的各种属性。


点击第二个图标,检查器中启用快速帮助(Quick Help)功能。在代码中点击任意位置,快速帮助面板会更新。


(2)文档管理程序

之间访问苹果公司的官方API文档的方法:按住Option键并且双击某个符号,就跳转到与该符号相关的文档中。如果按住Option键并且双击NSString,将会打开文档浏览器并搜索NSString,如图示:



6.调试运行

(1)Console & Scheme

shift+command+Y:显示控制台(Show/Hide the debug area)

shift + command + K:清除控制台(Clean)

option+command+R:编辑配置(Edit Scheme

(2)Build

Product -> Edit Schemeoption+command+R)->Info->Build Configuration:选择生成版本(Debug or Release)

command + B:构建(Buid)

(3)Target

一个定义好构建过程的Target成为一个Scheme,可在Scheme中定义Target的六种构建过程:Build/Run/Test/Profile/Analyze/Archive。

一个Target是指在一个Project中构建的一个产品,它包含了构建该产品的所有文件,以及如何构建该产品的配置。

Product -> Edit Schemeoption+command+R)->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。



(4)Issue & Errors

编译错误(error)和警告(warning)过多时,只显示编译错误


点击底端的感叹号,即可只显示编译错误,忽略编译警告:




(5)Run

command + R:运行(Run),可能会先编译。若按下control直接运行上次build的product(Run Without Building)。

command + .:停止运行(Stop)

(6)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



(7)Debug

F6:下一步(Step Over),逐过程单步调试,不进入函数体。

(fn+)F7:进入(Step Into)函数体。可能与多媒体键有冲突,故需要fn辅助。

(fn+)F8:跳出(Step Out)函数体。可能与多媒体键有冲突,例如呼叫iTunes,故需要fn辅助。

control+command+Y:逐断点(continue)继续执行。

trick:移动指令指针(Move the instruction pointer):


断点调试运行时,可以将绿色指针箭头(Line 47)移动到其他行(Line 49)或其他断点(Line 51)实现跳转执行。


(8)Watch

shift+command+M:Debug Workflow->View Memory

command+K:Debug Workflow->Clear Console

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或进行边界测试非常有用,可以避免在验证某个问题时反复改值重新编译。


(9)lldb调试命令

  • n/next:step over;
  • s/step:step into;
  • finish:step out;
  • c/continue:goto next breakpoint;
  • 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 [[[UIDevice currentDevice] 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)
  • 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)即可定位出异常调用的代码行位置。
  • memory write:改写指定地址的内存(Write to the memory of the process being debugged)。可help mem write查看帮助:

  • 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/item)的大小,默认为1byte。

    --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)起始地址+内存块count

(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

(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

Syntax: memory write <cmd-options> <address> <value> [<value> [...]]



(10)启用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基本操作》

0 0
原创粉丝点击