NSCFString上的EXC_BAD_ACCESS代码= 2

问题描述:

我在Objective C中有一个类来发现网络打印机。我确实找到了我的打印机,但是当我的代码稍后[在退出DiscoverDevices之后]检查为空/修剪设备列表时,它会抛出一个EXC_BAD_ACCESS code=2。我是Objective C新手,真的需要你的帮助。随意编码审查以及。NSCFString上的EXC_BAD_ACCESS代码= 2

我怀疑PrinterCallBack_PUT_bluetoothDevices([jsonString description]); 一些问题字符串格式/地址,但不知道

代码如下:

#import "DiscoverDevices.h"  
#import "ePOS-Print.h"  
#import "java_lang_String.h"; 
#import "org_json_me_JSONObject.h"; 

#define DISCOVERY_INTERVAL 0.5 

@interface DiscoverDevices() 
- (void)timerFindPrinter:(NSTimer*)timer; 
- (void)findStart;  
- (void) doNothing;  
@end  

@implementation DiscoverDevices  
@synthesize delegate = delegate_; 


- (id)init {  
    self = [super init];  
    if (self) {  
     printerList_ = [[NSMutableArray alloc] init];  
    }  
    [self findStart];  
    [self timerFindPrinter:timer_];  
    //TODO:find a better way to wait till printer is discovered here  
    // for now works  
    for (int i=0; i<500; i++) { 
     if (printerList_.count>0) { 
      break;  
     }  
     [self timerFindPrinter:timer_];  
    } 
    NSLog(@"-----printerList = %@",printerList_); 
    NSError * error;  
    NSMutableDictionary *dictObj = [[NSMutableDictionary alloc] init]; 
    for (int i=0; i<printerList_.count; i++) {  
     NSLog(@"printerList[%d] = %@",i,printerList_[i]);  
     [dictObj setObject:printerList_[i] forKey:printerList_[i]];  
     NSLog(@"jsonobject put [%d]",i);  
    }  
    NSLog(@"Dict : %@",dictObj);  
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictObj options:NSJSONWritingPrettyPrinted error:&error]; 
    if (!jsonData) {  
     NSLog(@"Got an error: %@",error);  
    } else {  
     NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];  
     jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@""];  
     jsonString = [jsonString stringByReplacingOccurrencesOfString:@" " withString:@""]; 
     NSLog(@"In native discoverDevices devices found jsonstring = %@, %s", jsonString, object_getClassName([jsonString class])); 

     if ([jsonString length]>2) {     
        // This is where we set the list of printers found. 
        com_nvsoft_s2pay_print_PrinterCallBack_PUT_bluetoothDevices([jsonString description]); 
        NSLog(@"In native discoverDevices written json to callback now reading...."); 
        NSLog(@"In native discoverDevices from cback json = %@, %s", com_nvsoft_s2pay_print_PrinterCallBack_GET_bluetoothDevices(),object_getClassName([com_nvsoft_s2pay_print_PrinterCallBack_GET_bluetoothDevices() class])); 
      }else{ 


      com_nvsoft_s2pay_print_PrinterCallBack_PUT_bluetoothDevices(nil);  
     } 

      com_nvsoft_s2pay_print_PrinterCallBack_PUT_result(1);  
      NSLog(@"In native discoverDevices completed jsondaata");  
     }  
     NSLog(@"In native discoverDevices exiting after jsondaata");  
     NSLog(@"In native discoverDevices from cback json = %@", com_nvsoft_s2pay_print_PrinterCallBack_GET_bluetoothDevices());  
     return self;  
    }  


- (void)dealloc  
{  
    [printerList_ release];  
    [super dealloc];  
} 
//find printer timer  
- (void)timerFindPrinter:(NSTimer*)timer  
{  
    NSLog(@"In timerFindPrinter");  
    int result = 0;  
    NSArray *items = [EpsonIoFinder getResult:&result]; 
    if(items != nil && result ==EPSONIO_OC_SUCCESS){  
     bool change = NO;  
     if([printerList_ count] != [items count]){  
      [printerList_ release];  
      printerList_ = [items retain];  
      change = YES;  
     }  
     /*if(change){  
     [self performSelectorOnMainThread:@selector(doNothing) withObject:nil waitUntilDone:YES];  
     }*/  
    }  
} 
    //find start/restart  
- (void)findStart  
{  
    NSLog(@"In findStart");  
    //stop old finder  
    [EpsonIoFinder stop];  
    //stop find timer  
    if(timer_ != nil){  
     [timer_ invalidate];  
     [timer_ release];  
     timer_ = nil; 
    } 
    //clear list 
    [printerList_ release];  
    printerList_ = [[NSMutableArray alloc] init];  
    //if(printerView_ != nil){  
    // [printerView_ reloadData];  
    //} 

    //find start 
     int result = [EpsonIoFinder start:EPSONIO_OC_DEVTYPE_TCP FindOption:@"255.255.255.255"];  
    if(result != EPSONIO_OC_SUCCESS){ 
      return ; 
     } 
    //start timer  
    timer_ = [NSTimer scheduledTimerWithTimeInterval:DISCOVERY_INTERVAL 
               target:self 
              selector:@selector(timerFindPrinter:) 
              userInfo:nil  
              repeats:YES];  
} 
@end 

我的控制台输出为:

2014-02-26 11:50:24.661 S2PayApp[10749:1807] -----printerList = (

    "192.168.0.13" 

) 

2014-02-26 11:50:24.662 S2PayApp[10749:1807] printerList[0] = 192.168.0.13 

2014-02-26 11:50:24.662 S2PayApp[10749:1807] jsonobject put [0] 

2014-02-26 11:50:24.663 S2PayApp[10749:1807] Dict : { 

    "192.168.0.13" = "192.168.0.13"; 

} 

2014-02-26 11:50:24.664 S2PayApp[10749:1807] In native discoverDevices devices found jsonstring = {"192.168.0.13":"192.168.0.13"}, __NSCFString 

2014-02-26 11:50:24.664 S2PayApp[10749:1807] In native discoverDevices written json to callback now reading.... 

2014-02-26 11:50:24.665 S2PayApp[10749:1807] In native discoverDevices from cback json = {"192.168.0.13":"192.168.0.13"}, __NSCFString 

2014-02-26 11:50:24.665 S2PayApp[10749:1807] In native discoverDevices completed 
jsondaata 

2014-02-26 11:50:24.666 S2PayApp[10749:1807] In native discoverDevices exiting after jsondaata 

2014-02-26 11:50:24.667 S2PayApp[10749:1807] In native discoverDevices from cback json = {"192.168.0.13":"192.168.0.13"} 

2014-02-26 11:50:24.667 S2PayApp[10749:1807] --3-- In native discoverDevices from cback json = {"192.168.0.13":"192.168.0.13"} 

2014-02-26 11:50:24.668 S2PayApp[10749:1807] completed discoveing ntwk printers 

2014-02-26 11:50:24.669 S2PayApp[10749:1807] devices r9= {"192.168.0.13":"192.168.0.13"},__NSCFString 

2014-02-26 11:50:24.669 S2PayApp[10749:1807] devices r4= {"192.168.0.13":"192.168.0.13"},__NSCFString 
(lldb) 

这里的确切类他的代码被破坏:

JAVA_BOOLEAN com_nvsoft_s2pay_util_StringUtil_isEmpty___java_lang_String(JAVA_OBJECT n1) 
{ 
    if (!__TIB_com_nvsoft_s2pay_util_StringUtil.classInitialized) __INIT_com_nvsoft_s2pay_util_StringUtil(); 
    //XMLVM_BEGIN_WRAPPER[com_nvsoft_s2pay_util_StringUtil_isEmpty___java_lang_String] 
    XMLVM_ENTER_METHOD("com.nvsoft.s2pay.util.StringUtil", "isEmpty", "?") 
    XMLVMElem _r0; 
    XMLVMElem _r1; 
    XMLVMElem _r2; 
    _r2.o = n1; 
    XMLVM_SOURCE_POSITION("StringUtil.java", 152) 
    //NSLog(@"In StringUtil devices r2= %@", _r2.o); 
    if (_r2.o == JAVA_NULL) goto label22; 
    XMLVM_CHECK_NPE(2) 
    _r0.o = java_lang_String_trim__(_r2.o); 
    // "" 
    _r1.o = xmlvm_create_java_string_from_pool(13); 
    //NSLog(@"In StringUtil devices r0= %@,%s", _r0.o); 
    //NSLog(@"In StringUtil devices r1= %@,%s", _r1.o); 

    //java_lang_String_equals___java_lang_Object[1] 
    XMLVM_CHECK_NPE(0) 
//************ Code breaks here 
    _r0.i = (*(JAVA_BOOLEAN (*)(JAVA_OBJECT, JAVA_OBJECT)) ((java_lang_String*) _r0.o)->tib->vtable[1])(_r0.o, _r1.o); 
    if (_r0.i != 0) goto label22; 
    // "null" 
    _r0.o = xmlvm_create_java_string_from_pool(9); 
    //java_lang_String_equals___java_lang_Object[1] 
    XMLVM_CHECK_NPE(2) 
    _r0.i = (*(JAVA_BOOLEAN (*)(JAVA_OBJECT, JAVA_OBJECT)) ((java_lang_String*) _r2.o)->tib->vtable[1])(_r2.o, _r0.o); 
    if (_r0.i == 0) goto label24; 
    label22:; 
    _r0.i = 1; 
    label23:; 
    XMLVM_EXIT_METHOD() 
    return _r0.i; 
    label24:; 
    _r0.i = 0; 
    goto label23; 
    //XMLVM_END_WRAPPER 
} 
+0

你在哪一行得到exc_bad_access?在日志输出中我看不到它的任何痕迹... – sergio

+0

转到产品 - >方案 - >编辑方案 - >诊断,选中标记'启用僵尸对象',然后在此放置跟踪。 – NeverHopeless

+0

启用僵尸并没有改变任何东西。相同的控制台输出和错误消息。我使用Codenameone生成的源代码和iOS本机代码。这里的代码可以工作,但是在退出这个类之后,它会失败。在下面的评论中附上代码。 – kpan

当你看到那种崩溃的故障是在其他地方。我猜你在某处导致了这种内存损坏。通常这是由调用具有错误参数类型的c函数或通过保持对GC对象的引用或保留对已发布Objective-C对象的引用来访问无效内存引起的。

你可以在xcode的左边看到崩溃时的调用堆栈,只需在那里的模式之间切换,你应该看到你的所有线程都有一个很好的堆栈,可以让你指出发生了什么。它有点混乱,虽然主要的iOS线程有点迟钝。