调用野指针
野指针定义:
C语言: 当我们声明1个指针变量,没有为这个指针变量赋初始值.这个指针变量的值是1个垃圾指 指向1块随机的内存空间。
OC语言: 指针指向的对象已经被回收掉了,这个指针就叫做野指针。
错误描述:message sent to deallocated instance
解决方案:NSZombieEnabled
e.g.:
NSArray *testArr = @[@"1"];
NSLog(@"111 %ld",testArr.retainCount);
[testArr release];
NSLog(@"222 %ld",testArr.retainCount);
NSLog(@"%@",testArr);
向僵尸对象发送消息
僵尸对象就是已经被释放的对象。指向僵尸对象的指针称为僵尸指针,属于野指针的一种。
错误描述:EXC_BAD_ACCESS(不能访问该存储器区域)
解决方案:NSZombieEnabled
e.g.:
UIView *view = [UIView alloc];
[self.view addSubview:view];
view只是分配了内存空间,并没有初始化,是僵尸对象,addSubview会造成崩溃。
向对象发送未定义的消息
错误描述:unrecognized selector sent to instance
解决方案:调试控制台会打印对应的消息方法和错误描述,用异常断点能定位到具体代码行。
e.g.:
NSArray *testArr = @[@"1"];
[testArr addObject:@"2"];
死锁
错误描述:EXC_BAD_INSTRUCTION
解决方案:解除死锁
e.g.:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
});
NSLog(@"3");
});
NSLog(@"4");
}
有这样一道面试题,请问程序执行输出是什么?如果你回答4、1、3、2或者4、1、2、3等等,那么恭喜,你成功被带入沟里。在这,不要忽略viewDidLoad就是在主线程执行,同步线程加入到主线程会形成死锁。程序直接崩溃。
内存泄漏
本不该放这,但是又不想重新写一篇只有几十个字的文章,暂且将就放这。
一般情况下,我们会使用Instruments来监测,当然能解决问题。
在这里我们要感谢伟大的Facebook工程师们,他们开源了一些自动化工具来解决监测内存泄露问题:FBRetainCycleDetector
、FBAllocationTracker、FBMemoryProfiler
原文介绍:Automatic memory leak detection on iOS
中文翻译:在iOS上自动检测内存泄露
bug跟踪
> bug跟踪是门艺术!通常在不清楚问题来源情况下可以二分法跟踪,粗略定位后开始断点调试。
概念
断点,其实就是一个让应用暂停运行的机制,这是为了方便开发人员执行调试,查看寄存器的某些值。
设置断点,让应用停在某一时刻,那么这一时刻应用所处的环境我们便一目了然,这个环境就是案发现场,断点就是帮助我们破案的工具。
Xcode快捷键:取消和添加断点"Command+"
设置断点后鼠标右键可以设置断点,如下图:
条件断点
在Edit Breakpoint中有Condition选项,可以设置条件表达式,当满足某一特定条件的前提下,该断点才生效。