0

私は iPhone アプリをプログラミングしていますが、メソッドの 1 つでメモリ管理について質問がありました。私は手動でメモリを管理することにまだ少し慣れていないので、この質問が初歩的なものに思えたら申し訳ありません。

以下は、数字パッドがタグに基づいてラベルにボタンを配置できるように設計されたメソッドです。この方法では、ボタンごとにメソッドを作成する必要はありません。メソッドは正常に機能します。関数で作成した変数を解放する責任があるかどうか疑問に思っています。

いずれかの変数を解放しようとするとアプリケーションがクラッシュするため、メモリに関する自分の責任について少し混乱しています。

メソッドは次のとおりです。

参考までに、変数 firstValue は私のラベルです。メソッドで宣言されていない唯一の変数です。

-(IBAction)inputNumbersFromButtons:(id)sender {
    UIButton *placeHolderButton = [[UIButton alloc] init];
    placeHolderButton = sender;

    NSString *placeHolderString = [[NSString alloc] init];
    placeHolderString = [placeHolderString stringByAppendingString:firstValue.text];

    NSString *addThisNumber = [[NSString alloc] init];
    int i = placeHolderButton.tag;

    addThisNumber = [NSString stringWithFormat:@"%i", i];

    NSString *newLabelText = [[NSString alloc] init];
    newLabelText = [placeHolderString stringByAppendingString:addThisNumber];

    [firstValue setText:newLabelText];

    //[placeHolderButton release];
    //[placeHolderString release];
    //[addThisNumber release];
    //[newLabelText release];

}

アプリケーションは最後の 4 行をコメントアウトしても問題なく動作しますが、ここでこれらの変数を解放する必要があるように思えます。私が間違っている場合は、関数で宣言された変数を解放する必要がある場合とそうでない場合について、簡単な説明を歓迎します。ありがとう。

4

4 に答える 4

3

はい、それらを解放する必要がありますが、関数の終わりを超えて少し長く必要です。

解決策はと呼ばれautoreleaseます。に置き換えるだけreleaseautorelease、プログラムが実行ループに戻るまでオブジェクトは残ります。

プログラムがそこに戻ったとき、オブジェクトの1つに関心のあるすべての人がretainそれにメッセージを送信する必要があります。これにより、によって解放されたときにオブジェクトの割り当てが解除されませんNSAutoreleasePool

実際に編集して、コードを見てください。もっと間違っています。例:

UIButton *placeHolderButton = [[UIButton alloc] init];
placeHolderButton = sender;

意味がありません。最初にオブジェクトを割り当て、次にそれを変数に割り当てます(へのポインタ)placeHolderButton。それはいいです。

次にsender、同じ変数に割り当てます。作成したオブジェクトへの参照は失われます。

私があなたが望むものを手に入れるかどうかはわかりませんが、これはより良いでしょう:

-(IBAction)inputNumbersFromButtons:(id)sender {
    UIButton *placeHolderButton = sender; // this is still a little useless, but ok

    int i = placeHolderButton.tag;
    NSString *addThisNumber = [NSString stringWithFormat:@"%i", i];

    NSString *placeHolderString = firstValue.text;

    NSString *newLabelText = [placeHolderString stringByAppendingString:addThisNumber];

    [firstValue setText:newLabelText];
}

割り当てがないため、リリースは必要ありません。これらの関数によって返される文字列はすでにautoreleasepoolに追加されているため、(必要に応じて)自動的に割り当てが解除されます。

于 2011-01-06T23:25:01.353 に答える
0

上手。使い終わったら解放します。早いほど良い。メモリ管理に不慣れな場合、一部のオブジェクトには注意が必要です。

次に、deallocメソッドでそれらを解放します。

自動リリースプールは便利な場合があり、パフォーマンスの問題によって意見が一致しない場合があります。

于 2011-01-06T23:26:35.927 に答える
0

new、alloc/init、または copy という単語を含むものはすべて解放する必要があります。

また、これを割り当て/初期化する必要はありません:

UIButton *placeHolderButton = [[UIButton alloc] init];
placeHolderButton = sender;

これを行う別の方法は次のとおりです。

UIButton *placeHolderButton = (UIButton *)sender;

あなたのバージョンでは、保持カウントが +1 のインスタンスを割り当てていますが、すぐに参照を置き換えているため、後でメモリを解放する方法はありません。

alloc/init を使用して多数のインスタンスを作成し、それらの参照を自動解放されたインスタンスに置き換えています。

あなたが使用できる

    NSString *placeHolderString = [placeHolderString stringByAppendingString:firstValue.text];

それ以外の

 NSString *placeHolderString = [[NSString alloc] init];
placeHolderString = [placeHolderString stringByAppendingString:firstValue.text];

これは、最初の行で作成された手動で管理されたインスタンスを、2 行目の自動解放されたインスタンスに置き換えています。

実際には、これのすべての alloc/init をファクトリ メソッドに置き換えることができ、自動解放されたインスタンスになるため、メモリをまったく処理する必要はありません。

-(IBAction)inputNumbersFromButtons:(id)sender {
    //cast sender as a UIButton to suppress compiler warning, and allow us to reference it as placeholder button
    UIButton *placeHolderButton = (UIButton *) sender;

    int i = placeHolderButton.tag;

    NSString *addThisNumber = [NSString stringWithFormat:@"%i", i];
    [firstValue setText:[firstValue.text stringByAppendingString:addThisNumber]];
}

NSString のクラス ドキュメントを見ると、その横に + が付いているメソッド (つまり、+stringWithString:(NSString *)string) はクラス メソッドです。alloc/init を呼び出した後は、これらのメソッドを参照で使用しないでください。その上で。

于 2011-01-06T23:44:09.047 に答える
0

UIButton で alloc/init を使用するのは不可解です。

私は常にファクトリメソッドを使用します。

UIButton* aButton = [UIButton buttonWithType:UIButtonTypeCustom];

これにより、目的の親ビューにすぐに追加する自動リリース ボタンが返されます。

現時点では確認できませんが、SDK が UIButton インスタンスをキャッシュし、バックグラウンドで最適化を行っているようです。UIButton ivar を保持しようとするたびに、パフォーマンスが低下しました (特に、画面に多くのサブ ビューがある場合)。

于 2011-10-24T07:08:20.607 に答える