私は自分自身のばかを作ることについてだけど、私はここの周りの多くの友好と患者の人々が気づいたので、私はちょうどそれを試してみる:iPhoneのメモリ管理
私がiPhoneアプリを開発しています、それは車のレビューのデータベースを含んでいます。ユーザーが電子メールでレビューを共有できるようにしたい。だから、彼/彼女はアプリで面白い車を見つけると、彼/彼女はボタンを押すだろうと、アプリは、iPhoneのMail.appを通じて電子メールを作成します。
今すぐ。私は初心者ですが、私はあまりにもiPhoneのメモリ管理に慣れていないと認めなければなりません。私が書いたコード、この特定のメール方法は、恐ろしい "プログラム受信シグナル" EXC_BAD_ACCESS ""メッセージでアプリケーションを終了します。グーグルの話によれば、これは悪いメモリ管理の結果であることが示唆されています。
私はこのことについて少しだけ理解していたので、明示的に初期化し、その後、狂人のようなすべての一時変数を解放しました。それにもかかわらず、「EXC_BAD_ACCESS」は表示され続ける。
私のアプリを殺すとすぐに、構築されたURLがMail.appを引き金にして、うれしく私のメールを作成します。
次のサンプルコードを検討し、私を撃ってください。あなたは自動解放するために設定されていますにもかかわらずeMailRowをリリースしている
:一見
- (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];
}
実際、私は[eMailRawのリリース]をコメントアウトしました。それ以来、いくつかのランダムなテストで、問題は発生しませんでした!どうもありがとうございます。 まだ、私はinit/releaseのことについて少し不安を感じています。私は本当にこのようなものを精神的に掃除する必要がありますか?それはちょっと過ちがちな縫い目です。 私はLazy Loadingについて読んでいます。それは私がここで使うべきものなのでしょうか?どのような利点があり、レイジーローディングは私のコードにどのように翻訳されますか? それは別の質問だと思いますが、どんな助けもありがとうございます。 –
メモリ管理ルールは非常に単純であり、知るためには絶対に重要です。そうでなければ、頻繁にあなたの髪を裂くでしょう。単純に、割り当て、コピー、または保持するものには、対応するリリースまたは自動リリースが必要です。オブジェクトのリリースが多すぎる(または少なすぎる)場合、EXC_BAD_ACCESSが与えられます。 遅延ロードによってこれらの基本ルールは変更されません。 – rein
何かを初期化する場合は、原則としてリリースする必要があります。一般的には、一時変数に便利なコンストラクタを使用して、メモリの管理を担当しないようにすることができます。ココアのメモリ管理を理解することは非常に重要です。 Appleのガイドは必読書です:間違いなく学習曲線はありますが、いったん大騒ぎを乗り越えると、それは驚くほど簡単です。 –
Chuck