ObjC object changes to random objects: a memory issue
long time listener, first time caller.
I have a basic memory issue I don't understand, that I'm sure just about any one of you will see in a second. I'm playing around, trying to learn various ways of using UIWebViews, getting strings from URLs, and so on. Specifically, I'm trying to obtain one URL from another. In other words, I have uploaded an html page to the web, containing a URL. The address for that page is coded into the app, giving me a "hook" into the app - I can change the contents of that page and send the app a new URL any time I want. Make sense?
So...retrieving the URL? No problem. Passing it into a string for later use - no problem. But when I set up a tap gesture recognizer, which should take that string, convert it back to an NSURL, and open it in Safari, I get a runtime crash. An NSLog call tells me that the string in question keeps being assigned to all sorts of random things.
The relevant bits of my code follow. I'm sure some of you will tell me there are much better ways to do what I want - and that's certainly welcome. But I'd also really love to know what I'm doing wrong for this particular implementation, as I'm sure it's a basic misunderstanding that I'd like to correct.
Thanks in advance. (And sorry about the formatting of the code block - haven't quite got the hang of posting on here!)
#import "Messing_With_Web_ViewsViewController.h"
@implementation Messing_With_Web_ViewsViewController
@synthesize tapView;
NSString *finalURL;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *firstString = @"http://www.my_web_address.html";
//Of course, I have the correct address here.
NSURL *firstUrl = [NSURL URLWithString:firstString];
NSError * error;
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:&error];
if ( finalURL )
{
NSLog(@"Text=%@", finalURL);
//everything fine up to here; console prints the correct
contents of "my web address"
}
else
{
NSLog(@"Error = %@", error);
}
//Taps
UITapGestureRecognizer *tapRecognizer;
tapRecognizer=[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(foundTap:)];
tapRecognizer.numberOfTapsRequired=1;
tapRecognizer.numberOfTouchesRequired=1;
[tapView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
}
- (void)foundTap:(UITapGestureRecognizer *)recognizer {
NSLog(@"Trying to load %@", finalURL);
//at this point the app开发者_运维问答 either crashes, or the console shows a random memory object
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: finalURL]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[finalURL release];
[super dealloc];
}
@end
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:&error];
The line above creates an instance of NSString which you do not own (because you did not call a method whose name includes 'new', 'alloc' 'retain', or 'copy' on it). That finalURL
with therefore eventually be destroyed when it is no longer needed. By the time your -foundTap:
method runs finalURL
has been deallocated and you are just referencing the memory location where it used to be and which now may contain some other object or random data.
Read the memory management guidelines again and also learn to run the static analyzer which should point out mistakes like this.
精彩评论