iOS:EXC_BAD_ACCESS错误NSString长度和setHTTPBody

时间:2013-03-30 04:46:02

标签: ios objective-c

当我启动模拟器并启动应用程序时,我点击了用户界面EXC_BAD_ACCESS NSString *strLength = [NSString stringWithFormat:@"%d", [postStr length]];[req setHTTPBody:[_postStr dataUsingEncoding:NSUTF8StringEncoding。我不知道为什么会这样。如果我卸载应用程序但保持模拟器打开并再次运行它我没有错误。任何帮助都会很棒。代码如下。

#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

1 个答案:

答案 0 :(得分:0)

熟悉with memory management and object lifetime rules。您的代码崩溃了,因为您没有在init...方法中保留(或复制)参数,并且它们正在被释放。将您的init ...方法更改为:

-(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;
}

请务必在dealloc方法中释放您正在复制或保留的三个实例变量。同时调用[super dealloc]作为该方法的最后一步,但这不是您现在问题的根源。

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

注意我从你的dealloc中移除了对[_baseURL release]的调用,因为你没有保留它,所以你不拥有该对象。如果您没有使用allocnew创建对象,并且未在其上调用retaincopy,那么您不拥有该对象,因此你不能释放它。