2009-02-24 11 views
6

iPhoneでオートレリーズがどのように機能しているのか不思議でした。私は、オブジェクトに自動解放を送信すると、は、autoreleaseが送信されたブロックのスコープの終わりまで、が保持されることが保証されています。あれは正しいですか?Autorelease scope

私は以下のようにapplicationDidFinishLaunchingにNIBからビューを初期化した

(void)applicationDidFinishLaunching:(UIApplication *)application { 

    loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease]; 

    [window addSubview: [loginViewController view]]; 
    [window makeKeyAndVisible]; 
} 

とビューが画面上にあったすべては今一度、私UIWindow

た、全く示しませんでしたコントローラーの初期化の最後からautoreleaseを取り除いて、そこからすべて滑らかになりました。

これは何についてですか?

乾杯、

K.

答えて

13

autoreleaseに電話すると、オブジェクトの所有権が現在の自動解放プールに渡されます。実行ループは、イベントを送出する(例:applicationDidFinishLaunching:)前に新しい自動解放プールを作成し、イベント終了時にそのプールを破棄します。

LoginViewControllerの所有権を自動解放プールに与えると、applicationDidFinishLaunching:が返された直後に解放されます。ビューコントローラが自身の割り当てを解除すると、スーパービュー(この場合はウィンドウ)からビューが削除されます。

アプリケーションデリゲートは、の方法で(またはログインが完了して別のビューに移動したとき)LoginViewControllerreleaseの所有権を保持する必要があります。

0

はautoreleasepoolは実行ループの終了時に洗浄されます。これは、メソッドを呼び出して処理する限り、それがまだ存在することを意味します。

コードにエラーは表示されませんが、この例ではウィンドウは正しく保持されています。

0

あなたはLoginViewControllerを自動解放プールに追加しているので、実行ループの最後に解放されています。それが起こると、そのビューも解放され、表示されなくなります。

+0

ビューはウィンドウに保持されます。しかし、私はドキュメントにアクセスすることはできません。 –

+1

しかし、ビューコントローラの割り当てを解除すると、ビューコントローラはスーパービューから管理しているビューを削除します。 –

+0

正確にDonが言ったこと。 –

4

Donの答えを拡張するには、「あなたは現在の自動解放プールにオブジェクトの所有権を与えます」と言うのがややこしいかもしれません。これは、自動解放プールが空になったときにオブジェクトが破棄されることが保証されることを意味すると誤解される可能性があります。これは正しくありません(この場合は発生しますが)。 -autoreleaseを送信すると、自動解放プールが排出されたときに-releaseメッセージが送信されるように要求されます。その-releaseメッセージがretainCount = 0になると、オブジェクトは破棄されます。

ドンが推奨していることをするには、このビューコントローラを追跡するためにivarを作成する必要があります。なぜそのビューが消えるのかについての彼の説明はまさに正しい。しかし、あなたはView Controllerをリークさせたくありません。あなたはそれを保持し、それを完了したときにそれをリリースしたいと思います。

@interface ... { 
    LoginViewController *_loginViewController; 
} 

@property (readwrite, retain) LoginViewController *loginViewController; 

@implementation ... 
@synthesize loginViewController = _loginViewController; 

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

    self.loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease]; 

    [window addSubview: [loginViewController view]]; 
    [window makeKeyAndVisible]; 
} 

- (void)dealloc { 
    [_loginViewController release]; _loginViewController = nil; 
    [super dealloc]; 
} 
関連する問題