2009-05-04 27 views
0

私は自分自身のばかを作ることについてだけど、私はここの周りの多くの友好と患者の人々が気づいたので、私はちょうどそれを試してみる: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]; 
    } 

答えて

3

うーん...。

これが問題になりますか?

+0

実際、私は[eMailRawのリリース]をコメントアウトしました。それ以来、いくつかのランダムなテストで、問題は発生しませんでした!どうもありがとうございます。 まだ、私はinit/releaseのことについて少し不安を感じています。私は本当にこのようなものを精神的に掃除する必要がありますか?それはちょっと過ちがちな縫い目です。 私はLazy Loadingについて読んでいます。それは私がここで使うべきものなのでしょうか?どのような利点があり、レイジーローディングは私のコードにどのように翻訳されますか? それは別の質問だと思いますが、どんな助けもありがとうございます。 –

+0

メモリ管理ルールは非常に単純であり、知るためには絶対に重要です。そうでなければ、頻繁にあなたの髪を裂くでしょう。単純に、割り当て、コピー、または保持するものには、対応するリリースまたは自動リリースが必要です。オブジェクトのリリースが多すぎる(または少なすぎる)場合、EXC_BAD_ACCESSが与えられます。 遅延ロードによってこれらの基本ルールは変更されません。 – rein

+0

何かを初期化する場合は、原則としてリリースする必要があります。一般的には、一時変数に便利なコンストラクタを使用して、メモリの管理を担当しないようにすることができます。ココアのメモリ管理を理解することは非常に重要です。 Appleのガイドは必読書です:間違いなく学習曲線はありますが、いったん大騒ぎを乗り越えると、それは驚くほど簡単です。 – Chuck