UIWebView loadRequest causing a crash in simulator - iphone

So I'm trying to load a simple URL (http://www.google.com) into a web view. I had this in the application I was working with, but boiled it down to a basic application to remove other variables. I have an absolute minimal application setup, one view controller with a webview as its primary view. For code I have
-(void)viewDidLoad
{
[super viewDidLoad];
UIWebView *webView = (UIWebView*)self.view;
NSMutableString *urlString = [[NSMutableString alloc] initWithString:#"http://www.google.com"];
NSURL* url = [[NSURL alloc] initWithString:urlString];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];
NSLog(#"Sending web request to %#", urlString);
[webView loadRequest:urlRequest];
[urlRequest release];
[url dealloc];
[urlString dealloc];
}
And when it loads, I get an EXC_BAD_ACCESS crash within the Web Thread. I am unsure if this is a problem related to the fact that I am working in the simulator, or something I've just screwed up with the setup.

DO NOT CALL dealloc. Call release on url and urlString instead.
This is because other objects have references to those objects, and when you say dealloc, you are explicitly destroying them. This is causing the EXC_BAD_ACCESS, because when other objects try to access the url and string objects, they have already been destroyed.
This is the whole point of reference counting. YOU are done with those objects, so if you say:
[url release];
[urlString release];
You are declaring that. This decrements the count of references to those objects. But up above, you said:
NSURL* url = [[NSURL alloc] initWithString:urlString];
This means url probably has a reference to that string. So it would have retained it when you created it. So after you release the string, it does not get destroyed because url still has a reference to it. When IT is done with it, it too will release it, and then (if no one else has claim to the object), it will automatically be dealloced, because its count will have dropped to zero.
Always keep in mind who else might be using your objects when you are dealing with this sort of memory management. You can read more about it in Apple's docs.

Related

How to download things without display hanging?

Okay. So I'm creating this app and I'm really happy with it apart from one thing. It uses a lot of internet database checking etc. and every time it does this it hangs until it has finished, spoiling the fluidity of the interface. Is there anyway to avoid this? Download stuff happens when you click a button or sometimes just as a result of an NSTimer. I would love for the user to be able to go through the interface fluidly and the app to update the info when it gets there. IS there anyway to do this?
EDIT - Current Synchronous code:
This is to download a CSV file:
NSString *link=[[NSString alloc] initWithFormat:#"http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=%#&callback=YAHOO.Finance.SymbolSuggest.ssCallback",timer.userInfo];
NSURL *url=[[NSURL alloc] initWithString:link];
NSData *dl=[[NSData alloc] initWithContentsOfURL:url];
NSString *str = [[NSString alloc] initWithData:dl encoding:NSUTF8StringEncoding];
This is to download a png file into a webView:
NSString *link=[[NSString alloc] initWithFormat:#"http://chart.finance.yahoo.com/z?s=%#&t=GOOG&q=m",self.Input.text];
url=[[NSURL alloc] initWithString:link];
[self.graph loadRequest:[NSURLRequest requestWithURL:url]];
It sounds like you're making synchronous requests. You shouldn't be doing that on the main thread. Your best option is probably to switch to asynchronous requests. You could make synchronous requests on a background thread, but that's more complicated and unnecessary in most situations.

Failing to connect to my WCF webget exposed service from objective c

This is a tough question.
When I press on the button, it is supposed to connect to a URL, which will initiate that method of my wcf service. However, when I debug, I noticed that the connection fails (like none of the delegate methods are called and stuff). I know that my WCF service works because when i type the URL in safari directly, it works perfectly, and performs that method. Here is my code:
- (IBAction)RBCButtonPressed:(id)sender {
//[[UIApplication sharedApplication] openURL:[NSURL URLWithString: #"http://10.1.51.55:8732/windows2/OnApplication?appName=RoyalBank.BankOfTheFuture.Surface.exe&directory=C:\\Program Files (x86)\\Bank of the Future"]];
NSString *urlString = #"http://10.1.51.55:8732/windows2/OnApplication?appName=RoyalBank.BankOfTheFuture.Surface.exe&directory=C:\\Program Files (x86)\\Bank of the Future";
NSLog(urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url ];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];
[request release];
if(connection)
self.valueReturned = [[NSData data] retain];
else
NSLog(#"data failed");
NSLog(#"connection failed");
[captureView addSubview:loader];
}
I'm not including the delegate methods cause they aren't called anyway.
It prints "connection failed."
UPDATE: When I use a method that takes in only one parameter, it works fine from both the browser and the device (the connection succeeds and the delegate methods are called). However, when there are two parameters, it works fine only from the browser. The connection always fails.
Possibilities - the use of the backslash confuses it somehow (?).
This is urgent and any help would be greatly appreciated.
EDIT: It will always print "connection failed" I realize, but I know that the connection fails because 1) the delegate methods aren't called and 2)the application does not turn on, which it will if the method is called.
If you check your NSURL object in the debugger, you'll find it's nil immediately after you try to initialize it. This is because it's malformed. Try URL encoding it first.
Notice the URL you pasted into safari changes to this:
http://10.1.51.55:8732/windows2/OnApplication?appName=RoyalBank.BankOfTheFuture.Surface.exe&directory=C:%5C%5CProgram%20Files%20(x86)%5C%5CBank%20of%20the%20Future
See all the %20s and %5Cs, etc.? That's because safari URL encodes it before sending the request. You must do the same.
Best regards.
It's failing because you are releasing connection right after you create it. If you're not using ARC, you could create it with autorelease, or just use ARC and forget about the releases.

Iphone: Need release using ASIFormDataRequest

i have one simple question, if i'm using ASIFormDataRequest when i need to release the request object?
NSURL *url = [NSURL URLWithString:#"url"];
ASIFormDataRequest *requestForm = [ASIFormDataRequest requestWithURL:url];
[requestForm addPostValue:[[NSUserDefaults standardUserDefaults] stringForKey:#"user"] forKey:#"user"];
[requestForm setRequestMethod:#"POST"];
[requestForm setDelegate:self];
[requestForm startAsynchronous];
Thanks
You need to remember that you are always responsible for releasing an object if the method from which you receive it contains new, copy, or init.
In this case, you don't need to release it. The ASIHTTPRequest class autoreleases it for you.
A quick search in the implementation file shows that it'll be autoreleased.
+ (id)requestWithURL:(NSURL *)newURL
{
return [[[self alloc] initWithURL:newURL] autorelease];
}
Your request is autoreleased in your code, so you don't need to release it (as others have said).
However, you are starting an asynchronous request - it'll complete/fail sometime in the future, and if it is associated with other objects which will get freed when the view exits you're potentially leaving yourself open to a crash. So I'd suggest you would want to make requestForm a property of your class (so when you assign the request to self.requestForm it will get retained for you), and explicitly release & nil it when the request completes.
If it's a very simple app with just one view you may get away without that though.

UIWebView memory issues

I am playing youtube videos on a UIWebView which appears as a modalViewController subview (flip transition). Everything works fine, even though the UIWebView is released, I still receive memory warnings after a few repeated selection of this modalViewController.
I have added my UIWebView programmatically inside ViewDidLoad. Inside viewDidDisappear I check for [UIWebView retainCount] and if greater than 1, perform the following steps:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[self.webView removeFromSuperview];
self.webView.delegate = nil;
self.webView = nil;
NSLog(#"[self.webView retainCount] %d", [self.webView retainCount]);
I am running my code on xCode 3.2.5, iOS 4.2.
Appreciate all you help.
I think you are approaching the memory management problem in the wrong way. Checking the retainCount is a valid debugging technique if you know what you are doing. It is not, however, a memory management tool. In your particular case, if the UIWebView is being displayed it will always have retain count > 1. The superview will have a retain on it thus making the "if" useless.
If the webView property is well defined (i.e. noatomic, retain) the statement:
self.webView = nil;
should release the webView. A common mistake is to initialize the property with:
self.webView = [[UIWebView alloc] init];
This is likely to introduce a leak if the webView is defined as "retain". The correct way is
self.webView = [[[UIWebView alloc] init] autorelease];
If you can't display your controller several times without running out of memory you have a memory leak. Use Instruments (Leaks in particular) to find hte objects what are note being released properly. This is a good tutorial.
Be careful in keeping your retains and releases balanced and check for leaks.
Your problem will be related to this:
Is it possible to prevent an NSURLRequest from caching data or remove cached data following a request?
Scroll down to my answer for an extension of the accepted answer - i had this problem for days and it's now resolved!

How can I create a single HTTP Get request for iPhone?

First of all, sorry for my posibly bad english...
I got a surely big stupid question...
In my enterprise have an automatic door system, that is opened with a HTTP GET request to a file.
Example:
http://ipaddress/rc.cgi?o=1,50
Where the o=number indicates the amount of seconds that the automatic door will run.
The is no need for authentification or nothing (that is made by LAN Radius).
So, the question is...
How can I make a single button (for example in the springboard) that when you touch it, runs the GET request?
You thing that it should be possible with NSURLConection ?
Thanks for all
I'm not sure if this is the best way of going about it, but this is how I've achieved something similar in my own app. Just create a new NSData object that hits the required URL, then release it if you don't need to do anything with the returned data:
NSURL *theURL = [[NSURL alloc] initWithString:#"http://ipaddress/rc.cgi?o=1,50"];
NSData *theData = [[NSData alloc] initWithContentsOfURL:theURL];
[theData release];
[theURL release];
Or just create an NSURLConnection to run asynchronously, then you don't have to worry about the UI hanging and if the delegate is set to nil, you can pretty much forget about it after you've run it.
NSURL * url = [NSURL URLWithString:#"http://ipaddress/rc.cgi?o=1,50"];
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url];
NSURLConnection * theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:nil];
[request release];
[theConnection release];