当我启动模拟器并启动应用程序时,我点击了用户界面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
答案 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]
的调用,因为你没有保留它,所以你不拥有该对象。如果您没有使用alloc
或new
创建对象,并且未在其上调用retain
或copy
,那么您不拥有该对象,因此你不能释放它。