0

どこにも答えが見つからないようです。iOS 向けの Objective-C 開発で手動メモリ管理を使用しています。

16 進文字列から UIColor を取得するための便利な関数を作成しました。その中で、それは戻ります

[[UIColor alloc] initWithRed:... alpha:alpha]

どうやら特定のプラットフォーム (iOS 8 ~ 9 のデバイスがいくつかあります) では、オブジェクトは関数の終了時に破棄されるため、返された UIColor* は使用できません。だから今、私たちはそれをに変更しました

[[[UIColor alloc] initWithRed:... alpha:alpha] retain]

私の質問は、このオブジェクトを使い終わったら、2 回解放する必要があるかどうかです。割り当てのために1回、保持のために1回?私には非常に奇妙に思えますが、これはオンラインでどこにも見つかりません。

保持しないと、(一部のプラットフォームでは) 関数を終了するときに割り当てが解除され、関数が役に立たなくなります。保持した場合、終了時に 2 回リリースする必要がありますか?

編集:

https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html

「...、通常、受け取ったメソッドまたは関数内で有効であることが保証されています。その範囲を超えて有効であり続けたい場合は、保持またはコピーする必要があります。」

だから、変なことをしているわけではありません。ドキュメントには、関数の範囲を超えて「有効なままにしておきたい」場合は「保持する必要がある」と書かれています。@FreeNickname が提案したことを試してみます。それは最も理にかなっています。

4

3 に答える 3

2

あなたが言った:

UIColor16 進文字列から取得するための便利な関数を作成しました。その中で、それは戻ります

[[UIColor alloc] initWithRed:... alpha:alpha]

Basic Memory Management Rulesによると、適切なメモリ管理はメソッドの名前によって決まります。

  • メソッド名が「alloc」、「new」、「copy」、または「mutableCopy」で始まらない場合は、autoreleaseオブジェクトを返す必要があります。

    - (UIColor *)colorWithHexString:(NSString *)hexString {
        ...
        return [[[UIColor alloc] initWithRed:... alpha:alpha] autorelease];
    }
    
  • メソッド名が「alloc」、「new」、「copy」、または「mutableCopy」で始まる場合、上記のようなオブジェクトを返すことができます。

    - (UIColor *)newColorWithHexString:(NSString *)hexString {
        ...
        return [[UIColor alloc] initWithRed:... alpha:alpha];
    }
    

    このパターンは、上記の の規則よりも一般的ではないことに注意してくださいcolorWithHexString

(注: メソッド名の接頭辞によって決定されるこのメモリ管理は、歴史的には単なるベスト プラクティスでしたが、現在では ARC コードとの相互運用性のために重要です。手動の参照カウント コードでは常に上記の規則に従ってください。)

ここで、コンビニエンス イニシャライザを呼び出しているコードがオブジェクトの割り当て解除を許可している場合、問題はコンビニエンス イニシャライザではなく、そのコードにあります。retainそれを呼び出す何かがそのメモリを適切に管理しないため、イニシャライザに余分なステートメントを追加し始めないでください。

代わりに、呼び出し元のコードが、それ自体の結果の適切なretain(そして最終的な) ことを確認してください。releasecolorWithHexString

ところで、Xcode の静的アナライザー ( shift+ command+ B) は、手動の参照カウント コードの分析と問題の特定に非常に優れています。


質問の編集で、ドキュメントを引用しました:

プログラムの他の場所からオブジェクトを受け取った場合、通常、受け取ったメソッドまたは関数内で有効なままであることが保証されます。その範囲を超えて有効なままにしたい場合は、retainまたはcopyそれを行う必要があります。既に割り当てが解除されているオブジェクトを解放しようとすると、プログラムがクラッシュします。

retainこれは、便利な初期化子がまたはを発行する必要があると言っているのではありませんcopy。上記で説明したように、 を呼び出すコードは、またはを介し​​て返されたオブジェクトcolorWithHexStringの所有権の独自の主張を確立する責任があると言っています。UIColorretaincopy

于 2016-06-04T17:11:47.827 に答える
0

あなたのような状況で使用される自動解放の概念を探していると思います。これは基本的に、遅延releaseメッセージを新しく作成されたオブジェクトに送信する方法であるため、呼び出し元はretain必要に応じてそれを受け取ることができます。それ以外の場合は、オブジェクトが処理されるときに破棄されautoreleasepoolます。

于 2016-06-04T15:33:00.667 に答える
0
于 2016-06-05T04:57:53.553 に答える