2009-07-31 7 views
1

3つの行を1つの行で行うには、どのような理由がありますか?それは、清潔でシンプル、かつ十分に簡単なようだラウンドアバウトでプロパティになるオブジェクトを初期化するのはなぜですか?

self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 

self.navigationController = aNavigationController; 

[aNavigationController release]; 

...と1つのラインで同じこと:ここで

developer.apple.comからいくつかのコードです。私は過去にプロパティが保持されていないという問題を抱えていました。オブジェクトの解放が原因でオブジェクトが破棄されました(これまでのところ、retain属性が設定されています)。 1行の式を使用すると、ダンディーのように動作します。

+0

私は、プロパティが時々保持されていなかった理由を理解しました。プロパティの値を設定するときにsetterメソッド(retain属性を実装する)ではなく、Class変数を使用する必要がありました.property =プロパティの代わりに=。あなたのすべての協力に感謝します! – JoBu1324

答えて

6

のObjective-C memory management rulesallocは、オブジェクトのインスタンスをINGのことで、あなたがそのインスタンスの(共有、他のオブジェクトに一度retainそれ)所有者であり、あなたがメモリリークを防ぐために、所有権を放棄したいときに、あなたがUINavigationControllerreleaseしなければならないことを指示します。ガベージコレクションされていない環境(iPhoneなど)では、allocまたはcopy(または「alloc」または「copy」を含むメソッド)の均衡をreleaseまたはautoreleaseとすることを意味します。あなたは(iPhoneのような)メモリ、限られた環境にautoreleaseの使用を避けることができれば、あなたの第二のスニペットは、その後

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease]; 

だろう、それが明示的releaseを使用することをお勧めします。 は、受信者を現在のNSAutoreleasePoolに追加します。この受信者は、その後プールのオブジェクトの「-release」を後で呼び出します。メモリ使用量に注意したいときは、「将来のある時」は良い考えではありません。したがって、iPhoneでは最初の例が標準的な使い方です。

+0

その場合、問題があります:selfが所有者によって解放されたとき、UINavigationControllerはそうではありませんか? – JoBu1324

+1

バリーは正確に正しい - 彼が言及したルールを読んでください。問題はあなたがそれを割り当てているので、あなたはそれを解放しなければならないということです。 navigationControllerプロパティは、それ自体を保持し、必要に応じて解放します。あなたがそれを解放しなければ(あなたの2番目の例で行ったように)、UINavigationControllerは決して解放されず、selfが解放された後でもリークします。 –

0

Objective-Cオブジェクト型のほとんどのプロパティは、宣言でretainまたはcopyを使用して宣言する必要があります。たとえば、あなたが言うかもしれない:

@property (retain) UINavigationController * navigationController; 

をそのような場合、自動的に書き込まsetNavigationController機能があなたのために保持呼ぶ、とワンライナーは次のようになります。

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease]; 

あなたがに実行されて設定しているプロパティが(保持)または(コピー)の代わりに使用(割り当て)されている場合の問題。その場合、セッターは単にそのポインタを他のポインタと等しくし、その後のオブジェクトの解放はそれをきれいにするでしょう。

また、autoreleaseではなくreleaseを呼び出している場合に問題が発生することがあります。

希望に役立ちます!

0

ここでプロパティをどのように定義したかによって、メモリリークが発生します。あなたがalloc/initコンボを参照すると、参照カウントが1のオブジェクトが返されます。あなたのプロパティがretainと定義されていると仮定すると、プロパティを設定すると、参照カウントが2に増加します。

あなたは本当にこのような何かを行く1行にすべてを維持したい場合:

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease]; 

も、それはのように自動解放オブジェクトに対して推奨されているが、彼らが必要以上に長く前後になることがあります。

+0

-autoreleaseは、単にこのオブジェクトを送信することを意味します。このような状況で-autoreleaseを使用しても、ナビゲーションコントローラは、すでに固執しているため、必要以上に長持ちすることはありません。私たちはivarに割り当てています。 –

+0

右... autoreleaseは、現在の自動解放プール内のオブジェクトへの参照を追加するだけです。それは実際にオブジェクトを解放するためにプールが排水されるのを待たなければならないので、これを長くする(この状況ではない)ことになります。このような状況では(オブジェクトは保持されているので問題はありませんが、この方法で自動解放オブジェクトに入るのは良い習慣ではありません。 – Lounges

関連する問題