2012-01-06 8 views
0

ビューのサブビューを隠したり削除したりするための最初の方法がなぜ機能するのかを理解することに苦労しています。この最初のメソッドでは、ポインタを参照渡しします。あまり一般的ではない第2の方法では、特定のビューを削除するために設計されたデリゲートメソッドがあります。最初の方法を使用したいと思っています。なぜなら、私はこれもまた適用したいという考え方がいくつかあるからです。最初のメソッドは、実装クラス内で呼び出される限り、確実に機能します。私が却下したいView Controllerから呼び出すと失敗します。最初のメソッドで失敗した場合、removeFromSuperview行でEXC_BAD_ACCESSを取得します。スーパービューからのビューの削除iOS

-(void)closeView:(UIViewController **)viewController 
{ 
[UIView transitionWithView:self.view 
        duration:UINavigationControllerHideShowBarDuration 
        options:UIViewAnimationOptionCurveLinear 
       animations:^ 
    { 
    [[*viewController view] setAlpha:0.0]; 
    } 
       completion:^(BOOL finished) 
    { 
    [[*viewController view] removeFromSuperview]; 
    [*viewController release], *viewController = nil; 
    }]; 
} 

-(void)closeButtonClicked 
{ 
[delegate closeView:&self]; 
} 

// 
// This method works without fail: 
// 

-(void)closeView 
{ 
[UIView transitionWithView:self.view 
        duration:UINavigationControllerHideShowBarDuration 
        options:UIViewAnimationOptionCurveLinear 
       animations:^ 
    { 
    // In this context viewController is defined in the class interface 
    [[viewController view] setAlpha:0.0]; 
    } 
       completion:^(BOOL finished) 
    {  
    [[viewController view] removeFromSuperview]; 
    [viewController release], viewController = nil;  
    }]; 
} 

-(void)closeButtonClicked 
{ 
[delegate closeView]; 
} 

答えて

2

まずは、スタイルガイドによるものではなく、一般的にこのようなメソッド内でviewControllerのリリースを行うのは良い考えではありません。それはすぐに問題にあなたを取得します。このメソッドの呼び出し元がviewControllerを処理している場合(retainを行った場合)、それを解放する必要があります。これは、最初の方法がView Controller自体の中で機能していない可能性があります。

2番目の方法では、viewControllerをパラメータとして渡さないため、コンテキストで定義する必要があります。

あなたは、あなたがどちらかnilにその変数を設定する必要はありません、この方法でのViewControllerを放出しない、とあなたは、単に通常のパラメータとして渡すことができる場合:

-(void)closeView:(UIViewController *)viewController 
{ 
[UIView transitionWithView:self.view 
        duration:UINavigationControllerHideShowBarDuration 
        options:UIViewAnimationOptionTransitionCrossDissolve 
       animations:^ 
    { 
    [[viewController view] removeFromSuperview]; 
    } 
       completion:nil]; 
} 

ますでしょうその後、呼び出しサイトで次の操作を行います。アニメーションが行われる前にアニメーションが暗黙のうちのViewControllerパラメータを含むブロックから参照されるすべてのオブジェクトを、保持ブロックするので、このように子供を解放する

[self closeView:childViewController]; 
[childViewController release]; childViewController = nil; 

それは安全。したがって、アニメーションブロックがそれを解放するまで、子のdeallocは呼び出されません。 これは、変数へのポインタを渡すため、最初のコード例では機能しません。つまり、アニメーションブロックは子を保持する必要があるかどうかわかりません。

私はなぜアルファを設定したいのかわかりませんが、上記の例では、アニメーションブロック内のビューを削除することもできます。詳しくはUIView Class Referenceをご覧ください。

+0

アルファを必要としないことについて助言いただきありがとうございます。これは良い知らせです。私の推論をもう少し説明して、なぜ私が削除されているビューを解放したいのかを理解させてください。私は、表示されている子ビューからアクションの処理を切り離すためにこれをやっています。私は親の意見が子供と何をすべきかを決めることを望みます。私は、このアクションのデフォルトのアクションが子ビューを削除して無効にすることを望まない。それが言われると、私は、親がビューから子供を取り除き、それを無効にすることがなぜ問題であるのか分からない。あなたは説明できますか? – banDedo

+0

追加されたコメントと同様に、removefromsuperviewはブロック内でアニメートされませんでした。私はまだアニメーションのアルファを補完ブロックに入れて、これを必要に応じて動作させる必要がありました。私は何か間違っているのですか? – banDedo

+0

@PatrickHogan申し訳ありませんが、あなたのコードを適切に適合させる必要がありました。オプション:パラメータでは、削除されたビューにアニメーションを適用するために、UIViewAnimationOptionTransitionオプションの1つを選択する必要があります。 CrossDissolveはおそらくあなたが望むものです。私はそれを示すためにコードを適合させます。 – fishinear

0

** viewcontrollerと&自己ではありません。 Objective-Cでは、サブビュー自体で[self.view removeFromSuperview]を実行します。親ビューコントローラではreleaseを実行するか、ARCではサブビューを別のビューに置き換えます。

+0

アドバイスをいただき、ありがとうございました。何が書かれたのかであなたのことを明確にすることができますか? – banDedo

関連する問題