今天偶然學習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類型的變量。