3

当我启动模拟器并且应用程序启动时,我点击我得到的用户界面EXC_BAD_ACCESSforNSString *strLength = [NSString stringWithFormat:@"%d", [postStr length]];和 for [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
4

1 回答 1

0

熟悉内存管理和对象生存期规则。您的代码正在崩溃,因为您没有保留(或复制)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;
}

Be sure to release the three instance variables you are now copying or retaining in your dealloc method. Also call [super dealloc] as the last step in that method but that's not the source of your problem right now.

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

Notice I removed the call to [_baseURL release] from your dealloc as you did not retain it so you do not own the object. If you didn't create an object with alloc or new, and didn't call retain or copy on it, then you don't own the object, so you must not release it.

于 2013-03-30T05:12:23.003 回答