iOS:EXC_BAD_ACCESS 错误 NSString 长度和 setHTTPBody

标签 ios objective-c

当我启动模拟器并启动应用程序并单击 UI 时,我得到 EXC_BAD_ACCESS for 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

最佳答案

熟悉 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它,那么你不拥有这个对象,所以你不能释放它。

关于iOS:EXC_BAD_ACCESS 错误 NSString 长度和 setHTTPBody,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15715068/

相关文章:

ios - 应用内购买是 “in review”,而应用二进制文件本身仍然是 “waiting for review”?这是什么意思?

ios - Swift 中的 TableView 页脚

ios - 通过 swift 将您设计的 IOS 应用程序连接到您的 Dynamics 365 CRM 解决方案?

objective-c - 有什么方法可以禁用 'message to nil not throwing an error' 行为(即我想要错误)?

ios - 嵌套的 UINavigationControllers 和 TabBarController

ios - pushViewController 无法快速在 xib 中工作

Objective-c block 生命周期 ARC

objective-c - 如何将 UIImage 添加到分组的 UITableViewCell,使其圆角?

objective-c - MBProgressHUD 阻塞界面直到操作完成

ios - 如何断言函数返回数组