一、lldb(gdb)常用的调试命令?
1> po:打印对象,会调用对象 description 方法。是 print-object 的简写
2> expr:可以在调试时动态执行指定表达式,并将结果打印出来,很有用的命令
3> print:也是打印命令,需要指定类型
4> bt:打印调用堆栈,是 thread backtrace 的简写,加 all 可打印所有thread 的堆栈
5> br l:是 breakpoint list 的简写
6> n:是换行
7> p:是打印这个对象所属的类,即其父类
二、如何调试BAD_ACCESS错误?
BAD_ACCESS在什么情况下出现?
访问了野指针,比如对一个已经释放的对象执行了release、访问已经释放对象的成员变量或者发消息。 死循环
如何调试BAD_ACCESS错误
1.重写object的respondsToSelector方法,现实出现EXEC_BAD_ACCESS前访问的最后一个object
2.通过 Zombie
3.设置全局断点快速定位问题代码所在行
4.Xcode 7 已经集成了BAD_ACCESS捕获功能:Address Sanitizer。 用法如下:在配置中勾选✅Enable Address Sanitizer
三、IB中User Defined Runtime Attributes如何使用?
User Defined 是一个Xcode中十分强大而不常使用的功能,它能够配置一些你在Interface Builder 中不能配置的属性,进而很大程度上提高开发效率。在项目中使用User Defined Setting可以定义一些Xcode编译使用的宏配置,为了实现App的一些常量或属性值在不同运行环境下配置不同,可以在User Defined Setting中定义一些有关应用程序的配置。
应用场景
1.实际开发中,对应于开发、测试、生产等不同环境,会使用多套域名,开发者在项目中设置User Defined,以达到域名因环境变化而不同的隔离效果;
2.可以设置布尔类型的属性对应于不同环境,这样可以控制不同环境设置不同变量,甚至执行不同代码。
配置步骤
1.创建新的User Defined Settings
在Xcode中选中TARGETS-->Build Settings选中上方导航栏Edior选项,下拉菜单Add Build Setting-->Add User Defined Setting;
或者直接在Build Settings下方菜单栏Levels右边点击+,即可创建新的User Defined Setting。
2.添加User Defined Setting内容
为区分配置选项,可将配置环境分为:Debug、Release和add-hoc等,分别配置不同的字符串以提供在代码中根据环境不同替换达到自动生成的效果。
3.配置Compiler Flags
此时必需告诉Xcode你需要在哪里引用User Defined Setting的属性值,指向的是哪一个User Defined Setting。在Build Phases中搜索你需要使用User Defiend Setting 的文件,然后给该文件加上Compiler Flags,以配置域名为例: -D'APP_SERVER_ID=@"$(server)"', 其中APP_SERVER_ID为宏名称,用来对应User-Defined Setting的名称即server。
Apple官方配置说明:Adding User Defined Runtime Attributes
- 如何使用
在选择的文件中,定义一个宏,宏的值即对应不同环境时User Defined配置值,在代码中引用宏,就可以做到自动根据部署环境替换相应配置了。
四、IBOutlet连出来的视图属性为什么可以被设置成weak?
可以用一张图概括:
五、apple用什么方式实现对一个对象的KVO?
当你观察一个对象时,一个新的类会动态被创建。这个类继承自该对象的原本的类,并重写了被观察属性的 setter 方法。自然,重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象值的更改。最后把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。
六、self 是类的隐藏参数,指向当前调用方法的这个类的实例。那 super 呢?
很多人会想当然的认为“ super 和 self 类似,应该是指向父类的指针吧!”。这是很普遍的一个误区。其实 super 是一个 Magic Keyword, 它本质是一个编译器标示符,和 self 是指向的同一个消息接受者!他们两个的不同点在于:super 会告诉编译器,调用 class 这个方法时,要去父类的方法,而不是本类里的。
七、objc中的类方法和实例方法有什么本质区别和联系?
类方法:(-)
类方法是属于类对象的
类方法只能通过类对象调用
类方法中的self是类对象
类方法中不能访问成员变量
类方法可以调用其他的类方法
类方法中不能直接调用对象方法
实例方法:(+)
实例方法是属于实例对象的
实例方法只能通过实例对象调用
实例方法中的self是实例对象
实例方法中可以访问成员变量
实例方法中直接调用实例方法
实例方法中也可以调用类方法(通过类名)
八、 什么情况使用 weak 关键字,相比 assign 有什么不同?
什么情况使用 weak 关键字?
在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如: delegate 代理属性
自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用 weak,自定义 IBOutlet 控件属性一般也使用 weak;当然,也可以使用strong。在下文也有论述:《IBOutlet连出来的视图属性为什么可以被设置成weak?》
不同点:
weak 修饰符表明该属性定义了一种“非拥有关系” (nonowning relationship)。在为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此行为与 assign 类似,不同之处在于,在 weak 属性所指的对象遭到销毁、释放时,该属性值也会清空(nil out)。而 assign 的“设置方法”只会执行针对“纯量类型/基本数据类型” (scalar type,例如 CGFloat 或 NSInteger 等)的简单赋值操作。
assign 可以用非 OC 对象,而 weak 必须用于 OC 对象。