iPhone Memory Management - iphone

I'm about to make a fool out of myself, but I've noticed many friendly and patient people around here, so I just give it a try:
I'm developing an iPhone app, that contains a database of car reviews. I want the user to be able to share the reviews by email. So, when he/she finds an interesting car in the app, he/she would hit a button, and the app composes an email through the iPhone's Mail.app.
Now. I'm a newbie, and I have to admit that I'm not too familiar with memory management on the iPhone. The code that I wrote, this specific mail method, exits the application with the scary "Program received signal: “EXC_BAD_ACCESS”" message. A bit of Googling suggest that this is the result of bad memory management.
With my little understanding of this matter, I started explicitly initializing and afterwards releasing all temporary variables, like a madman. Nevertheless, the “EXC_BAD_ACCESS” keeps on showing up.
Interesting point here: as soon as I kill my app, the constructed URL still triggers Mail.app, and happily creates the email for me.
Please consider the following sample code, and shoot me.
- (IBAction) sendCartoFriend
{
CarAppDelegate *appDelegate = (CarAppDelegate *)[[UIApplication sharedApplication] delegate];
//Read the html template
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *emailFile = [resourcePath stringByAppendingPathComponent:#"MailDummy.html"];
NSMutableString *eMailRaw = [[[NSMutableString alloc] initWithContentsOfFile:emailFile]autorelease];
//set the variables
NSString *carNamePlaceholder = [[NSString alloc] initWithString:#"CarTitle"];
NSString *carName = [[NSString alloc] initWithString:car.shortname];
[eMailRaw replaceOccurrencesOfString:carNamePlaceholder withString:carName options:NSCaseInsensitiveSearch range:NSMakeRange(0, [eMailRaw length])];
[carNamePlaceholder release];
[carName release];
NSString *carReviewPlaceholder = [[NSString alloc] initWithString:#"CarReview"];
NSString *carReview = [[NSString alloc] initWithString:car.review];
[eMailRaw replaceOccurrencesOfString:carReviewPlaceholder withString:carReview options:NSCaseInsensitiveSearch range:NSMakeRange(0, [eMailRaw length])];
[carReviewPlaceholder release];
[carReview release];
//there are 5 more of these find/replace actions. the "CarReview" though is the biggest. It might contain several hundred of characters.
//compose the message
NSString *eMailSubject = #"Nice little car!";
NSString *encodedSubject = [[NSString alloc] initWithString:[eMailSubject stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *eMailBody = eMailRaw;
NSLog(eMailBody);
NSString *encodedBody = [[NSString alloc] initWithString:[eMailBody stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *urlString = [[NSString alloc] initWithString:[NSString stringWithFormat:#"mailto:?subject=%#&body=%#", encodedSubject, encodedBody]];
NSURL *url = [[NSURL alloc] initWithString:urlString];
[urlString release];
[encodedBody release];
[encodedSubject release];
[eMailRaw release];
[[UIApplication sharedApplication] openURL:url];
[url release];
}

Hmm.. at first glance:
you're releasing eMailRow even though it's set to autorelease.
Could this be the problem?

Related

Problem uploading NSString to server

I am struggling to get one particular string to upload, using php and mysql I have a number of strings from textfields that will successfully go, this particular string is the text from a label in another viewcontroller. I can see the text with NSLog but for some reason it will not go, I'm confident the server side is working properly as I can pass other strings to that particular row in mySQL.
To get the text from the other view I am using
- (IBAction)submit:(id)sender;
{
GetLocation * getlocation =[[GetLocation alloc] initWithNibName:Nil bundle:nil];
getlocation.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
getlocation.rwanswer=self.rwanswer.text;
[self presentModalViewController:getlocation animated:YES];
[getlocation release];
}
in the first viewcontroller then in the view that is uploading to the server I synthesize the string.
NSString *rwanswer;
#property (nonatomic, copy) NSString *rwanswer;
I can see the text with NSLog but for some reason I cannot get it to upload.
-(IBAction)UploadData :(id)sender {
NSString *appname = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleDisplayName"];
NSString *result =rwanswer;
NSLog(#"result=%#", result);
NSString *comment =comments.text;
NSString *name = username.text;
NSLog(#"name=%#", name);
NSString *Website =[NSString stringWithFormat:#"http://www.ivectorn.com/Set/Submit.php?name=%#&comments=%#&appname=%#&results=%#", name, comment, appname, result];
[BackroundLoader loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:Website]]];
Any help would be great
I know this problem. I think the problem is by your Website-String. Try to Log int and you will see, that there are characters inside you cannot put in a URL. The following method will help you if this is your problem:
- (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding
Instead of
NSString *appname = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleDisplayName"];
NSString *result =rwanswer;
NSLog(#"result=%#", result);
NSString *comment =comments.text;
NSString *name = username.text;
To the following:
NSString *appname = [[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleDisplayName"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //Or your String Encoding
NSString *result = [rwanswer stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //Or your String Encoding;
NSLog(#"result=%#", result);
NSString *comment =[comments.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //Or your String Encoding;
NSString *name = [username.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //Or your String Encoding;
I hope this will help you. I struggled with the same problem some time ago.
Sandro Meier

How to use method stringWithContentsOfFile:encoding:error

I don't know how to use this method.
I want to get the data in an rtf file as a NSString, however I can not.
Here is part of my code.
NSString *filePath = #"path of the file";
NSString *ImagePath = [[[NSString alloc] init] autorelease];
imagePath = [NSString stringWithContentsOfFile: filePath encoding:(NSStringEncoding)nil error:(NSError**) nil];
I can't readout the data in that .rtf file. I am appreciate that everyone may help me. Thanks.
Try using this
imagePath = [NSString stringWithContentsOfFile: filePath encoding:NSUTF8StringEncoding error:nil];
Here is the function
NSString *content = [[[NSString alloc] initWithContentsOfFile:filepath
usedEncoding:nil
error:nil] autorelease];
before using this be sure u giving a right path (filepath) to the string.

memory leaking iPhone sdk?

I am trying out this application found over here: http://blog.objectgraph.com/index.php/2010/02/24/parsing-html-iphone-development/
this application is contantly crashing.. i think there is a mem. leaking could any one help me fix this
thanks
okay here is yar solution...
you released htmlData at the end. dont release it. cause you didn't alloc that...
NSData *htmlData = [NSData dataWithContentsOfURL:[NSURL URLWithString: #"http://www.objectgraph.com /contact.html"]];
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *elements = [xpathParser search:#"//h3"]; // get the page title
TFHppleElement *element = [elements objectAtIndex:0];
NSString *h3Tag = [element content];
NSLog(#"Html tags :%#",h3Tag);
mLabel.text = h3Tag;
[xpathParser release];

memory leaks this code

htmPath = [[NSBundle mainBundle] pathForResource:#"barcode" ofType:#"html"];
params = [[NSString alloc] initWithFormat:#"?data=%#",numberTextField.text];
fileURL = [NSURL URLWithString:[[[NSURL fileURLWithPath:htmPath] absoluteString] stringByAppendingString:params]];
[self.barView loadRequest:[NSURLRequest requestWithURL:fileURL]];
////htmpath,params are strings.
///fileurl is nsurl and in this i m calling appending two strings for the result.
///numberTextField.text is the textfield that will use this html for further functionality.
you have allocated the "params" and did not released it.
params = [[NSString alloc] initWithFormat:#"?data=%#",numberTextField.text];
you should release every allocated object.
[params release];

Continuous conversion of text to speech from json data

I am designing an app that needs text to speech. I am using the library that is posted here to convert text to speech. I have to retrieve text from Json url, and pass the values to text to speech. I am able to retrieve Json data and convert it to text to speech for the ObjectatIndex 0 using the following code...
SBJSON *json = [[SBJSON alloc]init];
fliteEngine = [[FliteTTS alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.sampleurl.txt"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *jsonstring = [[NSString alloc]initWithData:response encoding:NSUTF8StringEncoding];
NSArray *asanasList = [json objectWithString:jsonstring error:nil];
NSArray *asanas =[asanasList objectForKey:#"yogagurubackpain"];
for(NSDictionary *test in asanas)
{
UrlValues *myasanas = [[UrlValues alloc]init];
myasanas.asanatitle = [test objectForKey:#"asanatitle"];
myasanas.asanatranscript = [test objectForKey:#"asanatranscript"];
myasanas.asanapicture = [test objectForKey:#"asanapicture"];
[data.yoga addObject:myasanas];
[myasanas release];
}
UrlValues *asana=[[data yoga]objectAtIndex:0];
self.AsanaName.text = [asana asanatitle];
self.AsanaTranscript.text = [asana asanatranscript];
NSString *imageUrl = [asana asanapicture];
NSString* mapUrl = [imageUrl stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSData* imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:mapUrl]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
self.AsanaImage.image = image;
NSString *speak = self.AsanaTranscript.text;
[fliteEngine setVoice:#"cmu_us_rms"];
[fliteEngine speakText:speak];
[fliteEngine setPitch:100.0 variance:11.0 speed:0.4];
[imageData release];
[image release];
[jsonstring release];
[json release];
Now my problem is how can i go to the next object automatically after completion of the playing of first one. The process must continue for all the objects. The corresponding images etc must load on the page after the text to speech is done for the first one... Plz help me...
Looking at the source of the linked library, it looks like you'll have to hack a method into FliteTTS.m. If you look at the source, it's using an AVAudioPlayer to play back a generated WAV file. It's also setting itself as the audio player's delegate. If you implement the audioPlayerDidFinishPlaying:successfully: delegate method and play the next chunk when it's called, you should be able to have a semi-continuous text-to-speech stream.