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];  
       }]; 

}