2013-03-30 5 views
3

Lorsque je démarre le simulateur et que l'application démarre et que je clique sur l'interface utilisateur, j'obtiens EXC_BAD_ACCESS pour NSString *strLength = [NSString stringWithFormat:@"%d", [postStr length]]; et [req setHTTPBody:[_postStr dataUsingEncoding:NSUTF8StringEncoding. Je ne sais pas pourquoi cela arrive. Si je désinstalle l'application mais que le simulateur reste ouvert et que je l'exécute à nouveau, je ne reçois aucune erreur. Toute aide est la bienvenue. Le code est ci-dessous.iOS: EXC_BAD_ACCESS Erreur longueur NSString et setHTTPBody

#import "LocavoreRetroAPIAdapter.h" 
//Class extention declares a method that is private to the class 
@interface LocavoreRetroAPIAdapter() 
-(NSMutableURLRequest *)initRequest:(NSURL *)url method:(NSString *)method; 
@end 

@implementation LocavoreRetroAPIAdapter 

//Called when this class is first initialized 
-(id) initWithName:(NSString *)postStr webService:(NSString *)webService spinner:  (UIActivityIndicatorView *)spinner{ 
    if(self = [super init]){ 
     _postStr = postStr; 
     _baseURL = @"http://base/api/"; 
     _webService = webService; 
     _spinner = spinner; 
     _result = nil; 
    } 
    return self; 
} 

//Request to Locavore API restful web services 
-(void) conn:(NSString *)method{ 

    dispatch_queue_t concurrentQueue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(concurrentQueue, ^{ 
     __block NSDictionary *resultBlock = nil; 
     dispatch_sync(concurrentQueue, ^{ 
      /* Download the json here */ 

      //Create webservice address 
      NSString *webService = [_baseURL stringByAppendingString:_webService]; 

      //Create the url 
      NSURL *url = [NSURL URLWithString:webService]; 

      //Create error object 
      NSError *downloadError = nil; 

      //Create the request 
      NSMutableURLRequest *req = [self initRequest:url method:method]; 

      if(req != nil){ 
       //Request the json data from the server 
       NSData *jsonData = [NSURLConnection 
             sendSynchronousRequest:req 
             returningResponse:nil 
             error:&downloadError]; 
       NSError *error = nil; 
       id jsonObject = nil; 

       if(jsonData !=nil){ 

        /* Now try to deserialize the JSON object into a dictionary */ 
        jsonObject = [NSJSONSerialization 
            JSONObjectWithData:jsonData 
            options:NSJSONReadingAllowFragments 
            error:&error]; 
       } 


      //Handel the deserialized object data 
      if (jsonObject != nil && error == nil){ 
       NSLog(@"Successfully deserialized..."); 
       if ([jsonObject isKindOfClass:[NSDictionary class]]){ 
        resultBlock = (NSDictionary *)jsonObject; 
        //NSLog(@"Deserialized JSON Dictionary = %@", resultBlock); 
       } 
       else if ([jsonObject isKindOfClass:[NSArray class]]){ 
        NSArray *deserializedArray = (NSArray *)jsonObject; 
        NSLog(@"Deserialized JSON Array = %@", deserializedArray); 
       } else { 
        /* Some other object was returned. We don't know how to deal 
        with this situation, as the deserializer returns only dictionaries 
        or arrays */ 
       } 
      } 
      else if (error != nil){ 
       NSLog(@"An error happened while deserializing the JSON data."); 
      }else{ 
       NSLog(@"No data could get downloaded from the URL."); 
       [self conn:method]; 
      } 
     } 
    }); 
    dispatch_sync(dispatch_get_main_queue(), ^{ 

     /* Check if the resultBlock is not nil*/ 
     if(resultBlock != nil){ 
      /*Set the value of result. This will notify the observer*/ 
      [self setResult:resultBlock]; 
      [_spinner stopAnimating]; 
      } 
     }); 
    }); 
} 

//Configure the request for a post/get method 
- (NSMutableURLRequest *)initRequest:(NSURL *)url method:(NSString *)method{ 

    //Create the request 
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; 

    //Get the string length 
    NSString *strLength = [NSString stringWithFormat:@"%d", [_postStr length]]; 

    //Specific to requests that use method post/get 
    //Configure the request 
    if([method isEqualToString:@"POST"]){ 
     [req addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content- Type"]; 
     [req addValue:strLength forHTTPHeaderField:@"Content-Length"]; 
     [req setHTTPMethod:@"POST"]; 
    }else if([method isEqualToString:@"GET"]){ 
     [req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
     [req addValue:strLength forHTTPHeaderField:@"Content-Length"]; 
     [req setHTTPMethod:@"GET"]; 
    }else{ 
     return nil; 
    } 

    //Set the HTTP Body 
    [req setHTTPBody:[_postStr dataUsingEncoding:NSUTF8StringEncoding]]; 

    //Return the request 
    return req; 
} 

//Called when this object is destroyed 
- (void)dealloc { 
    NSLog(@"DEALLOC LocavoreRetroAPIAdapter"); 
    [super dealloc]; 
    [_baseURL release]; 
    [_result release]; 
} 

@end 
+0

est-ce que _postStr est une variable d'instance ou une propriété? –

+0

_postStr est une propriété – wwjdm

+0

Essayez 'product-> profile-> Zombies' et voyez où se bloque exactement l'application. Le profileur vous donnera une trace de pile du cycle 'retain-release' de l'objet qui a été accédé quand il est retenu, le nombre était de moins de 0. – tipycalFlow

Répondre

0

Familiarisez-vous avec le with memory management and object lifetime rules. Votre code plante car vous ne conservez pas (ou ne copiez pas) les arguments dans votre méthode init... et ils sont en cours de désallocation. Changer init ... méthode:

-(id) initWithName:(NSString *)postStr webService:(NSString *)webService spinner:  (UIActivityIndicatorView *)spinner{ 
    if(self = [super init]){ 
     _postStr = [postStr copy]; 
     _baseURL = @"http://base/api/"; 
     _webService = [webService copy]; 
     _spinner = [spinner retain]; 
    } 
    return self; 
} 

Assurez-vous de libérer les trois variables d'instance que vous copiez maintenant ou de maintenir dans votre méthode dealloc. Appelez également [super dealloc] comme dernière étape de cette méthode, mais ce n'est pas la source de votre problème pour le moment.

//Called when this object is destroyed 
- (void)dealloc { 
    NSLog(@"DEALLOC LocavoreRetroAPIAdapter"); 
    [_postStr release]; 
    [_webService release]; 
    [_spinner release]; 
    [_result release]; 
    [super dealloc]; 
} 

Avis Je retiré l'appel à [_baseURL release] de votre dealloc comme vous ne l'avez pas retenu si vous ne possédez pas l'objet. Si vous n'avez pas créé d'objet avec alloc ou new et que vous n'avez pas appelé retain ou copy, l'objet ne vous appartient pas, vous ne devez donc pas le libérer.

+0

peut être utilisé avec ARC – iPatel

+0

@iPatel Non, car ils appellent 'dealloc' et' release'. ARC ne le permet pas. –

+0

yupp ... à droite :) merci :) – iPatel