2

私は必要なときにUIに固執できる小さな「ローダー」を作成しました。 UISpinnerViewによく似ています。UIAnimationブロックを含む再帰的メソッド、適切に解放する方法

これは再帰的に呼び出される必要があるいくつかのロジック(この記事ではブロック内のコードを簡略化しています)を持っています。

- (void) blink { 

    tick++; 

    if (tick > kNumberOfLights) 
     tick = 0; 

    UIView *lightOne = [self viewWithTag:kLightStartIndex]; 
    UIView *lightTwo = [self viewWithTag:kLightStartIndex+1]; 

    [UIView animateWithDuration:0.5 
          delay: 0.0 
         options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut 
        animations:^{ 

         if (tick == 0) { 

          [lightOne setAlpha:kLightOn]; 
          [lightTwo setAlpha:kLightOff];        

         } else if (tick == 1) { 

          [lightOne setAlpha:kLightOff]; 
          [lightTwo setAlpha:kLightOn];  
         } 
        } 
        completion:^(BOOL finished){ 
          [self blink];  
        }]; 

} 

ビューはスーパービューに追加されたときに呼び出され[self blink]方法:私はこのようにそれを行います。

Loaderクラスにはオブジェクトが残っていないので、スーパービューで削除すると、 が解放されます。コンソールで

(20380,0xa0a29540) malloc: * mmap(size=2097152) failed (error code=12) * error: can't allocate region

とエラー:

__[LoaderClass blink]_block_invoke_2

問題は、私はビューを離すとアニメーションブロックが実行されている場合、終了ブロックが割り当て解除オブジェクトを呼び出すと、エラーが発生するということですデバッグナビゲータで

ビューをスーパービューから削除したときに、ビューを正しく破棄する方法を教えてください。

答えて

1

通常、リリースを無効にするのは悪い考えですが、この場合はルールの例外である可能性があります。

インスタンス変数:

BOOL isBlinking; 
BOOL releaseWhenDoneAnimating; 

初期isBlinking = NOとreleaseWhenDoneAnimating = NO。

- (void)release 
{ 
    if(!isBlinking) { 
     [super release]; 
     return; 
    } 

    releaseWhenDoneAnimating = YES; 
} 

- (void) blink { 

    isBlinking = YES; 

    if(releaseWhenDoneAnimating) { 
     [super release]; 
     return; 
    } 

    tick++; 

    if (tick > kNumberOfLights) 
     tick = 0; 

    UIView *lightOne = [self viewWithTag:kLightStartIndex]; 
    UIView *lightTwo = [self viewWithTag:kLightStartIndex+1]; 

    [UIView animateWithDuration:0.5 
         delay: 0.0 
        options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut 
       animations:^{ 

        if (tick == 0) { 

         [lightOne setAlpha:kLightOn]; 
         [lightTwo setAlpha:kLightOff];        

        } else if (tick == 1) { 

         [lightOne setAlpha:kLightOff]; 
         [lightTwo setAlpha:kLightOn];  
        } 
       } 
       completion:^(BOOL finished){ 
        [self blink];  
       }]; 

} 
関連する問題