[NSMutableURLRequest released]: message sent to deallocated instance - iphone

My app is calling the rqst_run method below in didViewLoad method but I've an error. Debugger reports the following error:
[NSMutableURLRequest released]: message sent to deallocated instance
I don't know where this variable get released
Declared in header file (interface section):
NSMutableString *rqst_error;
NSMutableData *rqst_data;
NSMutableDictionary *listing_items;
and I defined this method in implementation:
- (void)rqst_run
{
rqst_data = [[NSMutableData data] retain];
NSMutableURLRequest *http_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://www.feedserver.com/request/"]];
[http_request setHTTPMethod:#"POST"];
NSString *post_data = [[NSString alloc] initwithFormat:#"param1=%#&param2=%#&param3=%#",rqst_param1,rqst_param2,rqst_param3];
[http_request setHTTPBody:[post_data dataUsingEncoding:NSUTF8StringEncoding]];
rqst_finished = NO;
[post_data release];
NSURLConnection *http_connection = [[NSURLConnection alloc] initWithRequest:http_request];
[http_request release];
if(http_connection)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
if([rqst_data length]>0)
{
NSString *rqst_data_str = [[NSString alloc] rqst_data encoding:NSUTF8StringEncoding];
SBJsonParser *json_parser = [[SBJsonParse alloc] init];
id feed = [json_parser objectWithString:rqst_data_str error:nil];
listing_items = (NSMutableDictionary *)feed;
[json_parser release];
[rqst_data_str release];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Feed" message:#"No data returned" delegate:self cancemButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Problem" message:#"Connection to server failed" delegate:self cancemButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[rqst_data setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[rqst_data appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[rqst_data release];
[connection release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[rqst_data release];
[connection release];
rqst_finished = YES;
}

Your initialization
NSMutableURLRequest *http_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://www.feedserver.com/request/"]];
is a convenience constructor that has a built-in autorelease for the object you are initializing using the constructor. So by calling
[http_request release];
you are trying to release something that is auto-released. In other words, you are over-releasing.
You should only call release on objects that you allocate using the keywords,
"New", "Alloc", "Copy". or use "retain"

Line [http_request release]; is unnecessary as your object is autoreleased.

For creation of your NSMutableURLRequest you used method which returns aurora eased instance and you not responsible for it's release. If you use methods which require you perform -alloc, -copy, -retain than you responsible for releasing this instance.

Related

Connection Lost error while using NSURLConnection

I am facing connection lost issue while using NSURLConnection. I am using NSURLConnection for asynch download. I am downloading big file of size around 80MB. I am writing received data in file every time with proper file handling. After sometime I am getting error of connection "Connection Lost" in method of NSURLConnection delegate named didFailWithError. If I execute in simulator on Mac then it will take long time but file gets downloaded successfully without having Connection Lost error. Any suggestion how to avoid this error? or what is the reason behind this error?
Let me know if any detail is required. Please note that I have read similar kind of post but it didnt help me.
Find below code snippet and let me know if more information is required:
-(void) startDownloadFromURL:(NSString*)URLString
{
if(URLString == nil)
{
[delegate DownloadFailed:-1];
return;
}
//self.pstrBaseFilePath = filePath;
URLString = [URLString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSMutableURLRequest* pRequest = [[NSMutableURLRequest alloc] init];
[pRequest setURL:[NSURL URLWithString:URLString]];
if(gpUserDataManager.pstrSessionID == nil)
return;
[pRequest addValue:[#"ASessionID=" stringByAppendingString:gpUserDataManager.pstrSessionID] forHTTPHeaderField:#"Cookie"];
[pRequest setHTTPMethod:#"GET"];
[pRequest setTimeoutInterval:180];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:pRequest delegate:self];
[urlConnection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if([httpResponse statusCode] == 200)
{
}
else
{
//Start.NOODLE-13304
/* NSInteger iResponseCode = [httpResponse statusCode];
NSString* pstrStr = [NSString stringWithFormat:#"%d", iResponseCode];
//pTheConnection = nil;
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Response Error", #"")
message:pstrStr
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil] show];
*/
[AUserDataManager ProcessResponseCode:httpResponse.statusCode];
[self.urlConnection cancel];
[delegate DownloadFailed:httpResponse.statusCode];
//End.NOODLE-13304
}
//[self.pRecvdata setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if(self.recvdData == nil)
{
self.recvdData = [[NSMutableData alloc] init];
}
[self.recvdData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// bIsResponseOK = FALSE;
//
// [NSThread detachNewThreadSelector: #selector(SpinEnd) toTarget:self withObject:nil];
//
// pTheConnection = nil;
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Connection Error", #"")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil] show];
[self.urlConnection cancel];
[delegate DownloadFailed:-1];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection cancel];
[delegate DownloadCompleted:self.recvdData];
}
DownloadRequest *request = [[DownloadRequest alloc] init];
request.delegate = self;
[request startDownloadFromURL:strURL];

How to fetch the data from Google news by XML Parsing

I want to fetch Google news data by XML parsing and save it into an array. The XML is like this
http://news.google.co.in/news?pz=1&cf=all&ned=in&hl=en&output=rss
Well I parse xml some different way than others and being frank I really do not know which technique it is but I assure you it works fine for me and I have implemeted it successfully in so many projects. Have a look at my code where I load tweets from some profile
This is the function where I make call for parser.
-(void)loadtweet
{
#try
{
NSString *urlString = [NSString stringWithFormat:#"https://api.twitter.com/1/statuses/user_timeline.xml?screen_name=SrBachchan&count=5"];
NSLog(#"fetching data from--------> : %#",urlString);
NSString* escapedUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSMutableURLRequest *request1 = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:escapedUrlString]];
NSURLConnection *con=[[NSURLConnection alloc] initWithRequest:request1 delegate:self];
if(con)
truckData=[[NSMutableData data]retain];
}
#catch (NSException *exception)
{
UIAlertView *v = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Please Try Again Later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[v show];
[v release];
}
}
And these are the NSURLConnection delegate methods:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[truckData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[truckData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[tweets removeAllObjects];
#try
{
// [app.trucks removeAllObjects];
NSString *thexml=[[NSString alloc] initWithBytes:[truckData mutableBytes] length:[truckData length] encoding:NSUTF8StringEncoding];
NSArray *array=[thexml componentsSeparatedByString:#"<status>"];
NSLog(#"%d",[array count]);
for(int i=1;i<[array count];i++)
{
NSString *str=[array objectAtIndex:i];
NSArray *arr1=[str componentsSeparatedByString:#"<text>"];
NSString *data=[arr1 objectAtIndex:1];
NSRange ranfrom=[data rangeOfString:#"</text>"];
// nt.truckName=[data substringToIndex:ranfrom.location];
[tweets addObject:[data substringToIndex:ranfrom.location]];
}
}
#catch (NSException *exception)
{
UIAlertView *v = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Please Try Again Later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[v show];
[v release];
}
}
I have used some string functions to separate tags and stored the values in Array.
This is where you can start: NSXMLParser class reference.

Asynchronous connection not getting called

I want to create two connections in a single view controller class. I am using NSOperationQueue for this purpose. The two connections are created in two functions and push inside the queue .The problem is delegates are not called. Please help me out. Thanks you in advance
- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
NSInvocationOperation *invOperation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(createConnection1) object:nil];
NSInvocationOperation *invOperation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(createConnection2) object:nil];
NSArray *ops=[[NSArray alloc] initWithObjects:invOperation1,invOperation2,nil];
[queue addOperations:ops waitUntilFinished:YES];
}
-(void) createConnection1{
//create connection
NSLog(#"Create Connection 1");
url1 =[[NSMutableString alloc] initWithFormat:#"http://www.google.com/ig/api?weather=New Delhi"];
NSURLRequest *theRequest1=[NSURLRequest requestWithURL:[NSURL URLWithString:url1]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
theConnection1=[[NSURLConnection alloc] initWithRequest:theRequest1 delegate:self];
if (theConnection1) {
connectionCreated1=YES;
receivedData1 = [[NSMutableData data] retain];
NSLog(#"received data 1 %#",receivedData1);
//[theConnection1 setDelegate:self];
}
}
-(void) createConnection2{
//create connection
NSLog(#"Create Connection 2");
url2 =[[NSMutableString alloc] initWithFormat:#"http://www.google.com/ig/api?weather=Chennai"];
NSURLRequest *theRequest2=[NSURLRequest requestWithURL:[NSURL URLWithString:url2]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
theConnection2=[[NSURLConnection alloc] initWithRequest:theRequest2 delegate:self];
if (theConnection2) {
connectionCreated2=YES;
receivedData2 = [[NSMutableData data] retain];
//[theConnection2 setDelegate:self];
NSLog(#"received data 2 %#",receivedData2);
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
if (connectionCreated1==YES) {
[receivedData1 setLength:0];
}
else if (connectionCreated2==YES) {
[receivedData2 setLength:0];
}
else {
NSLog(#"did not receive response");
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
if (connectionCreated1==YES) {
[theConnection1 release];
xmlParser1 = [[NSXMLParser alloc] initWithData:receivedData1];
[xmlParser1 setDelegate:self];
[xmlParser1 parse];
}
else if(connectionCreated2==YES){
[theConnection2 release];
xmlParser2 = [[NSXMLParser alloc] initWithData:receivedData2];
[xmlParser2 setDelegate:self];
[xmlParser2 parse];
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"connection failed" message:#"" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (connectionCreated1==YES) {
[receivedData1 appendData:data];
}
else if(connectionCreated2==YES) {
[receivedData2 appendData:data];
}
else {
NSLog(#"data not received");
}
}
The URL you have given in the first link seems to be borken ... look at this "http://www.google.com/ig/api?weather=New Delhi".. there is space between new delhi. try this instead http://www.google.com/ig/api?weather=New+Delhi

[CFDictionary count]: message sent to deallocated instance

My app is calling the rqst_run method below in didViewLoad method but I've an error. Debugger reports the following error:
[CFDictionary count]: message sent to deallocated instance
and debug marker is placed on this line (in tableView numberOfRowsInSection method below):
if([self.listing_items count] > 0)
I don't know where this variable get released
Declared in header file (interface section):
NSMutableString *rqst_error;
NSMutableData *rqst_data;
NSMutableDictionary *listing_items;
and I defined this method in implementation:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if([self.listing_items count] > 0)
{
if([self.listing_items objectForKey:#"items"])
{
return [[self.listing_items objectForKey:#"items"] count];
}
}
}
- (void)rqst_run
{
rqst_data = [[NSMutableData data] retain];
NSMutableURLRequest *http_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://www.feedserver.com/request/"]];
[http_request setHTTPMethod:#"POST"];
NSString *post_data = [[NSString alloc] initwithFormat:#"param1=%#&param2=%#&param3=%#",rqst_param1,rqst_param2,rqst_param3];
[http_request setHTTPBody:[post_data dataUsingEncoding:NSUTF8StringEncoding]];
rqst_finished = NO;
[post_data release];
NSURLConnection *http_connection = [[NSURLConnection alloc] initWithRequest:http_request];
[http_request release];
if(http_connection)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
if([rqst_data length]>0)
{
NSString *rqst_data_str = [[NSString alloc] rqst_data encoding:NSUTF8StringEncoding];
SBJsonParser *json_parser = [[SBJsonParse alloc] init];
id feed = [json_parser objectWithString:rqst_data_str error:nil];
listing_items = (NSMutableDictionary *)feed;
[json_parser release];
[rqst_data_str release];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Feed" message:#"No data returned" delegate:self cancemButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Problem" message:#"Connection to server failed" delegate:self cancemButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[rqst_data setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[rqst_data appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[rqst_data release];
[connection release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[rqst_data release];
[connection release];
rqst_finished = YES;
}
NSMutableDictionary must be properly initialized before use. In your code you assign feed to listing_items and then release it. It haven't been retained so listing_items is also removed.
Try to init dictionary like this:
listing_items = [[NSMutableDictionary alloc] initWithDictionary:feed];
and all should work fine.
Instead of this
listing_items = (NSMutableDictionary *)feed;
Use this
self.listing_items = [NSMutableDictionary dictionaryWithDictionary:feed];
It's pretty clear that:
* You use the instance variable instead of the property to assign the value to listing_items
* You put an autoreleased value in this ivar.
listing_items = (NSMutableDictionary *)feed; is clearly your error because feed is an autorleased variable (and then will be deallocated at the end of the current runloop by definition.
Either declare a #property(retain) for listing_items and use it each time you want to assign (autoreleased) value to it (so that the property will manage the retain/release on assignation)
Or retain the stored value manually (but this is painful as you need not to forget to release the previous value before assigning a new one to listing_items each time... which is what the setter method does when called either directly or thru the property assignment)
i think you need to initialize your NSMutableDictionary. Right now its just a pointer pointing to feed. when feed gets released, it just points to nil.
in the viewDidLoad :
listing_items = [[NSMutableDictionary alloc] init];
or you need to retain the data:
listing_items = [(NSMutableDictionary *)feed retain];
SBJsonParser *json_parser = [[SBJsonParse alloc] init];
id feed = [json_parser objectWithString:rqst_data_str error:nil];
listing_items = (NSMutableDictionary *)feed;
[json_parser release];
When you release the json_parser, the dictionary it holds is released too.
So, as others said, you need to retain the dictionary obtained from json_parser.

Adding a new row in a UITableView

HI Everyone,
It is my first post here and this is my problem:
I am trying to get some data from a REST API call and show then in a UITableView.
This s what I am doing:
in the viewDidLoad: 1) here I initialize my array of things to show in the Table (that is empty at the beginning) 2) the table is loaded (with 0 rows) and 3) then the HTTP async call is issued.
Done this I do my stuff with the HTTP Response and when ready I call the reloadData on my table. Here the strange happens.
numberOfRowsInSelection returns me the correct number of rows
but
tableView:cellForRowAtIndexPath:indexPath for the indexPath.row always returns me zero!
so no new row is added to the table.
- (void)doJSONRequest{
responseData = [[NSMutableData data] retain];
NSString *addr = [[NSString alloc] initWithFormat:#"http://localhost:8080/blabla/v1/items?count=10"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:addr]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[addr release];
}
- (void)doJSONRequestWithURL:(NSString *)url{
responseData = [[NSMutableData data] retain];
NSString *addr = [[NSString alloc] initWithFormat:url];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:addr]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[addr release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//NSLog(#"[%#] connection:didReceiveResponse %#",[self class], response);
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//NSLog(#"[%#] connection:didReceiveData %#",[self class], data);
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"[%#]",[NSString stringWithFormat:#"Connection failed: %#", [error description]]);
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"NETWORK ERROR!"];
[alert setMessage:#"App will close"];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Close"];
[alert show];
[alert release];
[alert show];
[alert release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//NSLog(#"[%#] connectionDidFinishLoading %#",[self class], connection);
[connection release];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSDictionary *res = [NSDictionary dictionaryWithDictionary:[responseString JSONValue]];
NSDictionary *tmp = [res valueForKey:#"reviews"];
tmp = [tmp valueForKey:#"reviews"];
NSEnumerator *e = [tmp objectEnumerator];
NSDictionary *tmp_review;
int i=0;
while (tmp_review = [e nextObject]) {
//NSLog(#"tmp_review %#", tmp_review);
//NSLog(#"count %d", i++);
MyObject r = [... doing my staff...]
[reviews addObject: r];
[r release];
};
[reviewListTableView reloadData];
[responseString release];
}
- (void)viewDidLoad {
//- (void)initUI {
//review is the array where I put my data
//it is empty at the beginning
reviews = [[NSMutableArray alloc] initWithObjects:nil];
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [reviews count]
}
Sounds like you may not have properly implemented numberOfSectionsInTableView:. You should log indexPath.section in tableView:cellForRowAtIndexPath:indexPath to see what section value you are passing. You will have multiple indexPath.row values of zero because there is a zero row for each section.
add new object in the array and [mytableview reloadData];
Implement following data source return number of section to be present in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
In tableView:cellForRowAtIndexPath:indexPath check section number and do your operation.
Note: If you don't need sections you can remove it.