今天偶然学习iOS开发的时候碰到一个EXC_BAD_ACCESS的异常,经查资料得到的解释是由于访问了已经被回收了堆内存对象导致的,参考:
http://code.tutsplus.com/tutorials/what-is-exc_bad_access-and-how-to-debug-it--cms-24544
不过我的这个例子却不是因为这个原因导致的,请看例子:
1 #import <Foundation/Foundation.h> 2 3 @interface MyRectangle : NSObject 4 5 -(void) setWidth: (int) width; 6 7 -(void) setHeight: (int) height; 8 9 -(void) setWidth:(int)width andHeight: (int) height; 10 11 -(int) area; 12 13 @end 14 15 // Implemention 16 17 #import "MyRectangle.h" 18 19 @implementation MyRectangle { 20 int width; 21 int height; 22 } 23 24 -(void) setWidth: (int) w { 25 width = w; 26 } 27 28 -(void) setHeight: (int) h { 29 height = h; 30 } 31 32 -(void) setWidth:(int)w andHeight: (int) h { 33 width = w; 34 height = h; 35 } 36 37 -(int) area { 38 return width * height; 39 } 40 41 @end
main函数
1 #import <Foundation/Foundation.h> 2 #import "MySquare.h" 3 4 int main(int argc, const char * argv[]) { 5 @autoreleasepool { 6 // 反射 7 MyRectangle *rect = [[MyRectangle alloc] init]; 8 [rect setWidth:10]; 9 [rect setHeight:20]; 10 11 id x_id = [rect performSelector:@selector(area)]; 12 NSLog(@"selector got area is %@", x_id); 13 } 14 return 0; 15 }
原因就在于area返回的是一个int类型的数据,int类型其实是一个放在栈内存的值,把它赋给类型为id变量,id变量的意思是:编译器把它当成任意的对象类型。这样话的话,运行的时候area方法得到的值返回给x_id,然后再拿这值当作堆内存的地址,这里当然找不到此数据了,就会导致访问失败的错误了。
从上面的例子可以看出EXC_BAD_ACCESS异常的本意是指访问不到内存中这个地址的值,可能是由于些变量已经被回收了,亦可能是由于使用栈内存的基本类型的数据赋值给了id类型的变量。