iOS开发笔记--导致EXC_BAD_ACCESS问题的原因

本文详细介绍了Objective-C编程中EXC_BAD_ACCESS错误的根本原因,并通过一个具体的实例深入剖析了其背后的逻辑错误和内存管理问题。文章强调了内存泄露、错误释放和EXC_BAD_ACCESS错误之间的联系,旨在帮助开发者有效识别和解决此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 写程序遇到 Bug 并不可怕,大部分的问题,通过简单的 Log 或者 代码分析并不难找到原因所在。但是在 Objective-C 编程中遇到 EXC_BAD_ACCESS 问题的时候,通过简单常规的手段很难发现问题。这篇文章,给大家介绍一个常用的查找 EXC_BAD_ACCESS 问题根源的方法。

    首先说一下 EXC_BAD_ACCESS 这个错误,可以这么说,90%的错误来源在于对一个已经释放的对象进行release操作。举一个简单的例子来说明吧,首先看一段Java代码:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class Test{  
  2.         public static void main(String[] args){  
  3.                 String s = “This is a test string”;  
  4.                 s = s.substring(s.indexOf(“a”),(s.length()));  
  5.                 System.out.println(s);  
  6.                   
  7.         }  
  8. }  


    这种写法在Java中很常见也很普遍,这不会产生任何问题。但是到了 Objective-C 中,就会出事,考虑这个程序:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import <Foundation/Foundation.h>  
  2.   
  3. int main (int argc, const char * argv[]) {  
  4. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  5.         NSString* s = [[NSString alloc]initWithString:@”This is a test string”];  
  6.         s = [s substringFromIndex:[s rangeOfString:@"a"].location];//内存泄露  
  7.         [s release];//错误释放  
  8. [pool drain];//EXC_BAD_ACCESS  
  9. return 0;  
  10. }  


    这个例子当然狠容易的看出问题所在,如果这段代码包含在一个很大的逻辑中,确实容易被忽略。Objective-C 这段代码有三个致命问题:1、内存泄露;2、错误释放;3、造成 EXC_BAD_ACCESS 错误。

    1, NSString* s = [[NSString alloc]initWithString:@”This is a test string”]; 创建了一个 NSString Object,随后的 s = [s substringFromIndex:[s rangeOfString:@"a"].location]; 执行后,导致创建的对象引用消失,直接造成内存泄露。

    2,错误释放。[s release]; 这个问题,原因之一是一个逻辑错误,以为 s 还是我们最初创建的那个 NSString 对象。第二是因为从 substringFromIndex:(NSUInteger i) 这个方法返回的 NSString 对象,并不需要我们来释放,它其实是一个被 substringFromIndex 方法标记为 autorelease 的对象。如果我们强行的释放了它,那么会造成 EXC_BAD_ACCESS 问题。

    3, EXC_BAD_ACCESS。由于 s 指向的 NSString 对象被标记为 autorelease, 则在 NSAutoreleasePool 中已有记录。但是由于我们在前面错误的释放了该对象,则当 [pool drain] 的时候,NSAutoreleasePool 又一次的对它记录的 s 对象调用了 release 方法,但这个时候 s 已经被释放不复存在,则直接导致了 EXC_BAD_ACCESS问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值